class base {
public:
int getC() {return c;}
int a;
protected:
int b;
private:
int c;
}
class derived: public base {
public:
int getD() {return d;}
private:
int d;
}
Now, class derived has public member:
int getC() {return c;}
int getD() {return d;}
int a;
protected member:
int b;
private member:
int d;
I can't comfirm if int c; is a private member of class derived. It's clear that any new member function of class derived can't access c. So, if c is a private member of class derived, the member function of class derived should have right to access c. So c is a what kind of member of class derived?
A derived class doesn't inherit access to private data members. However, it does inherit a full parent object, which contains any private members which that class declares.
Have a look at this question
I will clarify this with an example.
Consider a house where public variables and methods are outside your
house. Anyone who knows your house(class object) can access them.
Protected variables and methods are like common areas in your house like hall, kitchen only members inside your house can access them.
Private members are like your parent's room (base class)(ie only your parent can go into their room and you don't know what is inside)
Now coming to the question each class access modifier has the following arrangement
base
private : int c;
protected : int b;
public : int getC() {return c;}
int a;
derived
private : int d; (derived will never know c's existense)
protected : int b; (base class's copy)
public : int getC() {return c;}
int a;
int getD() {return d;}
Related
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.
}
};
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 {
// ...
};
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()
I ran into an error yesterday and, while it's easy to get around, I wanted to make sure that I'm understanding C++ right.
I have a base class with a protected member:
class Base
{
protected:
int b;
public:
void DoSomething(const Base& that)
{
b+=that.b;
}
};
This compiles and works just fine. Now I extend Base but still want to use b:
class Derived : public Base
{
protected:
int d;
public:
void DoSomething(const Base& that)
{
b+=that.b;
d=0;
}
};
Note that in this case DoSomething is still taking a reference to a Base, not Derived. I would expect that I can still have access to that.b inside of Derived, but I get a cannot access protected member error (MSVC 8.0 - haven't tried gcc yet).
Obviously, adding a public getter on b solved the problem, but I was wondering why I couldn't have access directly to b. I though that when you use public inheritance the protected variables are still visible to the derived class.
A class can only access protected members of instances of this class or a derived class. It cannot access protected members of instances of a parent class or cousin class.
In your case, the Derived class can only access the b protected member of Derived instances, not that of Base instances.
Changing the constructor to take a Derived instance will solve the problem.
protected members can be accessed:
through this pointer
or to the same type protected members even if declared in base
or from friend classes, functions
To solve your case you can use one of last two options.
Accept Derived in Derived::DoSomething or declare Derived friend to Base:
class Derived;
class Base
{
friend class Derived;
protected:
int b;
public:
void DoSomething(const Base& that)
{
b+=that.b;
}
};
class Derived : public Base
{
protected:
int d;
public:
void DoSomething(const Base& that)
{
b+=that.b;
d=0;
}
};
You may also consider public getters in some cases.
As mentioned, it's just the way the language works.
Another solution is to exploit the inheritance and pass to the parent method:
class Derived : public Base
{
protected:
int d;
public:
void DoSomething(const Base& that)
{
Base::DoSomething(that);
d=0;
}
};
You have access to the protected members of Derived, but not those of Base (even if the only reason it's a protected member of Derived is because it's inherited from Base)
You can try with static_cast< const Derived*>(pBase)->Base::protected_member ...
class Base
{
protected:
int b;
public:
...
};
class Derived : public Base
{
protected:
int d;
public:
void DoSomething(const Base& that)
{
b += static_cast<const Derived*>(&that)->Base::b;
d=0;
}
void DoSomething(const Base* that)
{
b += static_cast<const Derived*>(that)->Base::b;
d=0;
}
};
class Derived : public Base
{
protected:
int d;
public:
void DoSomething()
{
b+=this->b;
d=0;
}
};
//this will work
Following the hack for stl I wrote a small code which seems to solve the problem of accessing the protected members in derived class
#include <iostream>
class B
{
protected:
int a;
public:
void dosmth()
{
a = 4;
}
void print() {std::cout<<"a="<<a<<std::endl;}
};
class D: private B
{
public:
void dosmth(B &b)
{
b.*&D::a = 5;
}
};
int main(int argc, const char * argv[]) {
B b;
D d;
b.dosmth();
b.print();
d.dosmth(b);
b.print();
return 0;
}
Prints
a=4
a=5
Use this pointer to access protected members
class Derived : public Base
{
protected:
int d;
public:
void DoSomething(const Base& that)
{
this->b+=that.b;
d=0;
}
};