C++ Exclude classes inherited through base class in derived class - c++

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.

Related

C++ inheritance private members

I have a question about inheritance:
For example I have a base class A with private members: x, y
I have getter functions getx and gety,
I want to use the getter functions from A to class B that inherits from A,
But my problem is that x and y are private members of A
I cant access the private of A from B.
So I need to create two x,y for class B but that way I wont be able to use the get functions of class A.
Any help? I dont know how I can access the private members of A without creating new ones. Maybe with the constructor? But I am not sure how.
Private members are always private. They can't be accessed from outside classes at any cost. You can try protected instead, consider the following:
#include <iostream>
// Base class
class A {
protected: // declaration for protected vars which are clearly accessible to B
int x;
int y;
public:
void setX(int w) { x = w; }
void setY(int h) { y = h; }
};
// Derived class
class B: public A { // derives A
public:
int multiply() {
return (x * y); // accesses x and y from class A
}
};
The x and y are accessed from Class A to derived Class B.
That's it.
C++ provides the Protected mechanism which you might want to use. Take a look here.
You could make members x and y of Class A protected so that Class B which inherits from A can access them.
class A{
protected:
int x;
int y;
};
class B : public A{
public:
void somefn(int someval){
x = someval; //A::x is being set here.
}
};

Access to specific private members from specific class

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 {
// ...
};

Multiple level friendship

In code below:
class B {
int x;
int y;
};
class A {
friend class Other;
friend class A;
int a;
B* b;
public:
A(){ b = new B();}
};
struct Other {
A a;
void foo() {
std::cout << a.b->x; // error
}
};
int main() {
Other oth;
oth.foo();
}
The indicated line fails with:
t.cpp:22:19: error: 'x' is a private member of 'B'
std::cout << a.b->x;
^
t.cpp:7:5: note: implicitly declared private here
int x;
Why friendship is not working when referring from class member to other class member?
This line:
std::cout << a.b->x;
involves accessing a private member of A (b) and a private member of B (x) within class Other. While A gave access privileges to Other, B did not, hence the error. If you want this to work, you'll need to add:
class B {
friend class Other;
};
Side-note, this declaration is meaningless:
class A {
friend class A;
};
A class already has access to its own private members. So calling it its own friend is redundant.
Although this is a weird use of friends, I assume it is for learning purposes. That said, you should fix your friends definition like this:
class B{
friend class Other; // Because you access private member x from Other::foo()
int x;
int y;
};
class A{
friend class Other; // Because you access private member b from Other::foo()
int a;
B* b;
public:
A(){ b = new B();}
};
struct Other{
A a;
void foo(){
// Access A's private member b
// Access B's private member x
std::cout << a.b->x;
}
};
Try this:
class B{
friend class Other;
int x;
int y;
};

Can't access protected member

I have some difficulties understanding the following code. I have 3 classes: A, B and C. A has a private x of type int. B inherits A and everything from it. C inherits from B but protected. This means that both X and Y become inaccessible in class C. Also, get_x() and get_y() become protected in class C. So C should be able to acces the get_x() and get_y() functions but not x and y?
#include<iostream>
using namespace std;
class A
{
int x;
public: A(int i):x(i){}
int get_x(){ return x; }
};
class B: public A
{
int y;
public: B(int i,int j):y(i),A(j){}
int get_y(){ return y; } };
class C: protected B
{
int z;
public: C(int i,int j,int k):z(i),B(j,k){}
int get_z(){ return z; }
};
int main()
{
C c(1,2,3);
cout<<c.get_x();
cout<<c.get_y();
cout<<c.get_z();
return 0;
}
It seems like you understood 'protected inheritance' right but misunderstood 'protected members and methods'.
protected methods are inaccessible from outside of class.
Meaning
C c(1,2,3);
cout << c.get_x(); // THIS DOES NOT WORK.
where you can access get_x() is within class C.
class C: protected B
{
int z;
public: C(int i,int j,int k):z(i),B(j,k){}
int get_z(){ return z; }
int get_x_from_c() { return this->get_x(); } // THIS IS ALLOWED.
};
Here Even Object of type C class can not use the functions of class A and B. If you want access of member functions then make public access of B to C.
do this ...
class c : public B{.. then it will be able to access functions but remember not the member variables.

static variable for each derived class [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Overriding static variables when subclassing
I have a set of classes that are all derived from a base class. Any of these derived classes declare the same static variable. It is however specific to each of the derived classes.
Consider the following code.
class Base {
// TODO: somehow declare a "virtual" static variable here?
bool foo(int y) {
return x > y; // error: ‘x’ was not declared in this scope
}
};
class A : public Base {
static int x;
};
class B : public Base {
static int x;
};
class C : public Base {
static int x;
};
int A::x = 1;
int B::x = 3;
int C::x = 5;
int main() {}
In my base class I wanted to implement some logic, that requires the knowledge of the derived-class-specific x. Any of the derived classes has this variable. Therefore I would like to be able to refer to this variable at base class scope.
This wouldn't be a problem if it were a simple member variable. However, semantically, the variable is indeed not a property of the derived class' instance, but rather of the derived class itself. Therefore it should be a static variable.
UPDATE I need the class hierarchy to preserve its polymorphic nature. That is, all my derived class' instances need to be members of a common base class.
Then however, how can I get my hands on this variable from the base class method?
You can use the Curiously recurring template pattern.
// This is the real base class, preserving the polymorphic structure
class Base
{
};
// This is an intermediate base class to define the static variable
template<class Derived>
class BaseX : public Base
{
// The example function in the original question
bool foo(int y)
{
return x > y;
}
static int x;
};
class Derived1 : public BaseX<Derived1>
{
};
class Derived2 : public BaseX<Derived2>
{
};
Now classes Derived1 and Derived2 will each have a static int x available via the intermediate base class! Also, Derived1 and Derived2 will both share common functionality via the absolute base class Base.
With a virtual getter function
class Base {
public:
bool foo(int y) const{
return getX() > y;
}
virtual int getX() const = 0;
};
class A : public Base {
static const int x;
int getX() const {return x;}
};
class B : public Base {
static const int x;
int getX() const {return x;}
};
class C : public Base {
static const int x;
int getX() const {return x;}
};
int A::x = 1;
int B::x = 3;
int C::x = 5;
int main()
{
C c;
bool b = c.foo(3);
}