I have a class
class A
{
.....
private:
int mem1;
int mem2;
}
I have another class B which need to access only to mem1.
class B
{
....
}
How can I access private member mem1 from only from class B? I don't want to use friend. This means access to all private members.
With some rearrangement to class A (which might not necessarily be acceptable), you can achieve this:
class Base
{
friend class B;
int mem1;
};
class A : public Base
{
int mem2;
};
This exploits the fact that friendship is not transitive through inheritance.
Then, for class B,
class B
{
void foo(A& a)
{
int x = a.mem1; // allowed
int y = a.mem2; // not allowed
}
};
You can write a base class with member mem1 and friend B
class Base {
protected:
int mem1;
friend class B;
};
class A: private Base {
// ...
};
Related
In C++, is it possible to exclude a class inherited in the base class, from a subclass?
For example, if you have three classes like so:
class A
{
public:
int x;
};
class B : public A
{
public:
int y;
};
class C : public B
{
public:
int z;
};
Is it possible for class B to contain the variables x and y, while class C only contains y and z?
I think the closest thing to what you want to achieve is private inheritance.
struct A
{
int x;
};
struct B : private A
{
int y;
};
struct C : B
{
int z;
};
int main()
{
C c;
c.x = 5; // error. you're not allowed to access members from A
c.y = 3; // ok
c.z = 4; // ok
}
So the data of A is still going to be there but you just can't access it from outside of B.
If you want the data to not exist in C at all then the answer is No. Inheritance is literally having the content of your parents in the beginning of your struct.
struct A
{
int x;
};
struct B : A
{
int y;
};
in memory an instance of B will look like this:
struct B
{
int x;
int y;
}
Yes, it's possible to meet your variable inheritance constraints. Use friend classes. With the friendship semantics exposed by the keyword friend inside a class declaration, you can make a derived class to have access to the private members of its parent class. The link contains a full tutorial of the friendship semantics.
Your code would look like:
class A
{
private:
int x;
friend class B;
};
class B : public A
{
public:
int y;
};
class C : public B
{
public:
int z;
};
With this, class B has access to the private x of class A, but only from inside the definition of class B. Your variable inheritance constraint is met, class B contains (and can use) x and y, while class C contains y and z.
Another way could be by private inheritance, like this:
class A
{
private:
int x;
};
class B : private A
{
public:
int y;
};
class C : public B
{
public:
int z;
};
But this is much more stricter than the friend approach. Choose which one suits your need.
There are three classes, A, B, C;
Class A is friends with B, B has a protected data member. Class C inherits publicly from Class A. Can I access those protected data members of B by initializing a B object in a function of C?
If not how would I Go about accessing the values of B in C functions?
You cannot access the protected members of B directly in C but you could introduce a protected method in A that gets/sets the protected member in B; since C is derived from A you could access the protected get/set methods in A from C, see example below. Probably best to think about the overall design though.
class A
{
protected:
int getValueOfB(B& b) { return b.protectedValue; }
void setValueInB(B& b, int value) { b.protectedValue = value; }
};
class C
{
void doSomething()
{
B b;
setValueInB(b, 1);
}
}
friend are NOT inherited.
In the same way friend of friend are NOT friend.
As alternative, passkey idiom might help in your case:
class B;
class A
{
public:
struct Key{
friend class B; // no longer in class A.
private:
Key() = default;
Key(const Key&) = default;
};
// ...
};
class C : public A
{
private:
void secret(Key /*, ...*/) { /*..*/ }
};
class B
{
public:
void foo(C& c) {
c.secret(A::Key{}); // Access C private thanks to "private" key from A.
}
};
class A
{
private:
int a,b,c;
public:
virtual int get()=0;
friend class B;
};
class B{
//here I want to access private variables of class A that is a, b and c
};
class C:public class A
{
int get(){
//some code
}
};
How to access private members of class A in class B. I cannot create an object of class A since it is abstract. I somehow have to use an object of class C to do that but how?
class A {
friend class B;
private:
int x;
public:
A() : x(42) {}
};
class C : public A {
};
class B {
public:
int reveal_secrets(C &instance){
// access private member
return instance.x;
}
int reveal_secrets(){
// access private member of instance created inside B
C instance;
return instance.x;
}
};
void print_secrets(){
C instance;
B accessor;
std::cout << accessor.reveal_secrets(instance) << ", " << accessor.reveal_secrets() << std::endl;
}
class B will have to have an instance object to work with in the first place. That instance object is what B will look at in order to access a, b, etc .
I am put/get value in/from subclass B from object of base class A. But I am not able to assign or get the value. My code is:
class A
{
};
class B: A
{
string SID;
};
class C: A
{
string Name;
};
class D : A
{
string Name;
};
class E
{
A a;
UINT32 AccessLevel;
};
.......
main()
{
E e;
}
Using object of e am trying to get the value of subclass B.
I need to get the SID from the class B?
Thanks,
The C++11 standard 11/3 says:
Members of a class defined with the keyword class are private by default.
at 11.2/2
In the absence of an access-specifier for a base class [...] private is assumed when the class is defined with the class-key class.
and at 11.2/1:
If a class is declared to be a base
class for another class using the private access specifier, the public and protected members of the base
class are accessible as private members of the derived class.
So what does that mean? First of all:
class A {};
class B : A {};
Here A, by virtue of 11.2/2 is inherited privately. This may be okay if you want to inherit variables and you want to implement getter/setters for a variable only in a derived class, but that's usually considered bad style.
In your case however, as stated by 11/3, your members are not inherited at all because they are private members:
class A
{
public:
int a; // inherited
protected:
int b; // inherited
private:
int c; // NOT inherited
};
and especially
class A { int a; };
is equivalent to
class A { private: int a; };
So you could make your members accessable from within your derived classes by making them public or protected (see 11.2/1):
class A { public: int a; };
class B : A {}; // privately inherits a
and if you wanted to make it acessable from outside of your derived classes you will have to inherit as public as well:
class A { public: int a; };
class B : public A {}; // publicly inherits a
but that's not what you usually would do. It's considered better style to make variables private and expose only getters and setters for those:
class A
{
public:
int get_a() const { return a_; }
void set_a(int val) { a_ = val; }
private:
int a_;
};
class B : public A {}; // now publicly inherits the getters and setters
// but not a_ itself
Why is that protected members in the base class where not accessible in the derived class?
class ClassA
{
public:
int publicmemberA;
protected:
int protectedmemberA;
private:
int privatememberA;
ClassA();
};
class ClassB : public ClassA
{
};
int main ()
{
ClassB b;
b.protectedmemberA; // this says it is not accesible, violation?
//.....
}
You can access protectedmemberA inside b. You're attempting to access it from the outside. It has nothing to do with inheritance.
This happens for the same reason as the following:
class B
{
protected:
int x;
};
//...
B b;
b.x = 0; //also illegal
Because the protected members are only visible inside the scope of class B. So you have access to it here for example:
class ClassB : public ClassA
{
void foo() { std::cout << protectedMember;}
};
but an expression such as
someInstance.someMember;
requires someMember to be public.
Some related SO questions here and here.
You can only access protectedmemberA from within the scope of B (or A) - you're trying to access it from within main()