Please consider the scenario below:
class A
{
friend void B::Itemfunction();
private:
int number;
int size;
public:
Randomfunction();
}
class B : public A
{
private:
string Random;
public:
void Itemfunction();
void CheckLog();
}
Would it be possible for an object made in Itemfunction of type A to access the private data members of obj? Such as:
void B::Itemfunction(){
A obj;
//Possible to do...
obj.number = 2;
}
I understand that the derived class B can access all the public parts of A, but if I wanted just one function (Itemfunction) to access the private parts would this be the correct way of doing it? I just want to see if my understanding is correct.
Cheers
In your code, where you implement Itemfunction
, you are creating a new, completely unrelated object of type A
locally. In inheritance, your B
object has an internal subobject of type A
. You can access the fields of A
directly within B
. However, you can't access private members. Your friendship trick will not work; you cannot declare a method of B
a friend until you see B
s definition, but B
can't be defined until A
is defined, and as you can see we're going in circles. What you can do instead is to make that member protected:
class A
{
protected:
int number;
private:
int size;
public:
Randomfunction();
}
void B::Itemfunction() {
number = 2;
}
No, it's not possible. You cannot friend a class member function for a class that isn't yet completely declared.
The only way in that case (since class B
needs a completely declared class A
to inherit), is to forward declare class B;
and friend the whole class:
#include <iostream>
#include <string>
class B;
class A
{
// friend void B::Itemfunction();
friend class B;
private:
int number;
int size;
public:
void Randomfunction();
};
class B : public A
{
private:
std::string Random;
public:
void Itemfunction();
void CheckLog();
};
int main()
{
}
This has a chicken and egg problem. Both B
must be fully defined for A
to see B::Itemfunction
.
class A
{
friend void B::Itemfunction(); <-- Itemfunction does not exist yet
private:
int number;
int size;
public:
int Randomfunction();
};
class B: public A
{
private:
std::string Random;
public:
void Itemfunction();
void CheckLog();
};
Swapping the order won't work either because B
needs A
to be defined to inherit from A
.
class B: public A <-- A does not exist yet
{
private:
std::string Random;
public:
void Itemfunction();
void CheckLog();
};
class A
{
friend void B::Itemfunction();
private:
int number;
int size;
public:
int Randomfunction();
};
Solution 1 is forward define class B
so the compiler knows that B exists, even if it knows nothing about it, and then friend
the whole class, because A
only knows B
exists. OP's friend
relationship is maintained.
class B; <-- forward definition of B
class A
{
friend class B; <-- friending all of B, not just the function
private:
int number;
int size;
public:
int Randomfunction();
};
class B: public A
{
private:
std::string Random;
public:
void Itemfunction();
void CheckLog();
};
BUT! All of B
now has complete access to all of A
. If A
wants to keep size
or any other members hidden and under it's control, tough. B
can call all of A
's functions and change all of A
's member variables. B
can totally pown A
.
This also doesn't scale to other subclasses. B
can see all of A
, but C
and D
cannot.
So say you have a less trivial example where A
cannot allow anyone to mess with the value of size
. Maybe it's the capacity of an internal array, and changing size
will result in A
running past the end of allocated memory. The reason doesn't matter much here; for the sake of this example no one but A
is allowed to change size
.
This leads us to solution 2: protected access and accessor functions.
class A
{
protected: <-- all inheritors can access members in this block. No one else can
int number;
private: <-- only A can access members in this block
int size;
public:
int Randomfunction();
int getSize() <-- accessor function to provide read-only access to size
{
return size;
}
};
class B: public A
{
private:
std::string Random;
public:
void Itemfunction(); <-- can do anything to number and read size
void CheckLog(); <-- so can this
};
class C: public A
{
private:
std::string member;
public:
void doStuff(); <-- and this
void DoOtherStuff(); <-- and this
};
B
and C
can access A::number
and can use A::getSize
to see the value of size
. number
can be changed by B
and C
, but size
cannot. If you are worried about the cost of calling a function to read size
, don't be. When the compiler is done with A::getSize
, you won't even know it's there. It probably isn't.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.