Learning inheritance - c++

I am trying to understand inheritance and I need some help building two classes. The fist one is called A, the second one is called B.
A has one private integer value "m_a". It has two constructors, the default one sets m_a to 5. and another one which takes as an argument an integer called m and sets m_a's value to m. As for member functions it will have two. The first one will return m_a. The second one will print "Hello from A!". Let's move on to B. B will have a private string m_s. A default constructor which will set m_s to "asd" or to anything other than an empty string and a constructor which will take as an argument a string and set m_s to it's value. As far as functions go, firstly B will have a function that will return m_s. It will have a function which will have the same name as the print "Hello from A" function in A which will override it and it will printout "Hello from B!" instead (is that polymorphism ?).
Those are the classes needed. I have the following questions (I will post what I have created below)
Firstly, is there any way I can get to the private data fileds from the base class. For example let's say I want to take the m_s variable, add it to another one and print out their sum. Is that possible ? (and how)
Also when I try to create a class with a constructor different from the default one I get errors. I am obviously doing something wrong. The question is what.
I think those are all of my questions for now, so it is time for me to post the source code.
#include <iostream>
#include <string>
using namespace std;
class A
{
private:
int m_a;
public:
A(){m_a = 5;}
A(int m)
{
m_a = m;
}
void pm()
{
cout << "Hello from A!" << endl;
}
int get_a()
{
return m_a;
}
};
class B : A
{
private :
string m_s;
public:
B(){m_s = "asd";}
B(string s)
{
m_s = s;
}
void pm()
{
cout << "Hello from B!" << endl;
}
string get_s()
{
return m_s;
}
};
int main()
{
A a(10);
a.pm();
cout << a.get_a() << endl;
B b("asd");
b.pm();
cout << b.get_s() << endl;
cout << b.get_a() << endl;
return 0;
}

(is that polymorphism ?).
Not the way you have done it. It would be polymorphism if you had a pointer of type A* which pointed to what was actually a B object, and calling pm on that pointer correctly invoked the member function of B. This would only be possible if the pm function in A were declared as virtual, like below.
class A
{
...
virtual void pm(){
...
};
...
int main()
{
A* = new B();
A->pm(); //"Hello from B!"
}
is there any way I can get to the private data fileds from the base class
Not sure what you mean here - your example talks of a private field of the derived class.
Typically good class design means that derived class should not need to access the (private) fields of the base class, if this is needed you should make that field protected.
As to the compile error #ArunKumar got it exactly.
When you say Class B : A You inherit from A, but all the members are inherited as private by default, due to this, base class constructor is private, so you cannot use it.
However when you say Class B : public A it is the other end of the spectrum. All members of the base class retain their accesibility in the derived class (public remains public, etc)

The problem is that you're using private inheritance:
class B : A {
Inheritance through classes are private by default. Add public before A.
class B : public A {
As for your other problem...
I want to take the m_s variable, add it to another one and print out their sum.
This is easy when it comes to std::string. Just create another member function:
void addTom_s(string s) { m_s += s; }

Trying changing class B : A to class B : public A

Related

Complex object inside another one

I have the following class
class A {
private:
B b;
public:
A();
}
class B {
public:
void foo();
void bar();
void foz();
........
}
B has a lot of methods. Sometimes is needed for a "customer" of class A to use method of class B. I could return a reference of B, but in this case I should return a const reference because returning a non-const reference of a private object is not good programming. If the reference is const, foo, bar and so on can't be called because they aren't const. So the only "clean" way seems to recreate the same interfaces in A using delegation to B. But this approach is not really good because I should recreate all the interfaces in A. As alternative I could set B as public in A, but it seems "strange" to me. What should I do in this case?
That is mainly an encapsulation question, and what you want to advertise in the public interface of class A.
If class B is also a public class - read can normally be used by users of class A and not a class internal to a library or framework - and if you want the existence of a B subobject to exist in the public documentation of class A and if you want to allow any operation on the B object, you can safely provide a getter.
If any of the above conditions is false, then the getter would break encapsulation and you would better define delegating methods in class A.
Depending on the general design, it could make sense to declare an interface class (say C) with only the methods that you want to allow from class A, and have B a subclass from C. Then you could safely declare a getter returning a reference on a C object:
class C {
public:
void foo(); // optionally virtual or pure virtual...
void bar();
void foz();
};
class B: public C {
.... // other members not relevant for what is public for A users
};
class A {
private:
B b;
public:
A();
C& getB() {
return b;
}
};
Solution 1. You create a getb() and return reference to B. Its not bad programming in you case particularly.
Solution 2. Create interface function for each corresponding function of b and call them.
void A::foo()
{
b.foo();
}
You can make the data member protectedinstead of private. Documentation says that protected members are not as private as private members, which are accessible only to members of the class in which they are declared, but they are not as public as public members, which are accessible in any function. protectedmembers (be they data members of method members) serve the role you're looking for : they are not accessible from everywhere (safe coding practices), but you can still manage them in clean ways when it makes sense :
If class A has an attribute of type B, is has access to B's
protected and publicmembers
friendfunctions can access both protected and publicmembers of a class they are friend with.
When preceding the name of a base class, the protected keyword specifies that the public and protected members of the base class are protected members of its derived classes.
Here, you're interested by the first item of the list : you can access B' methods from A; BUT B has still safeguards.
When I run the following code (adapted from your code) :
#include <iostream>
using std::cout;
using std::endl;
class B {
public:
void foo() { cout << "foo" << endl; };
void bar() { cout << "bar" << endl; };
void foz() { cout << "foz" << endl; };
};
class A {
protected: // <===== THIS IS THE SIGNIFICANT BIT
B b;
public:
A() {
b.foo();
b.bar();
b.foz();
cout << "A constructor" << endl;
};
};
int main(int argc, char** argv) {
A myA;
return 0;
}
I get the following console output :
foo
bar
foz
A constructor
Which shows that I can access B's methods from A.

c++ : How to bind inherited methods only to parent classes?

i've stumbled upon this problem while doing multi-base inheritance project for my college work. Example of my problem, and code itself: I'm setting up 3 classes, A, B and C.
B inherits publicly from A.
C inherits publicly from B.
I want to set a method publicly in B, that does take as argument a pointer to an object of class A. However it should be able to use only class A objects, neither B or C.
Problem is that Visual Studio 2013 doesn't show any error, and simply allows for my method to be used by B class object on a C class object, which is exactly the opposite of what i want to achieve. Why is that happening?
Does that mean that inheriting somewhat makes C object being interpreted as of type A, B and C at the same time? If not, is there a direct way to bind a method to be used only on classes that it inherits from (c methods on both A and B objects)? Feel free to correct me if i'm wrong anywhere, i'm still a newbie at programing. Thank you for your help! `
class A
{
private:
int x;
string z;
public:
void SetZ()
{
cout << "Set Z: ";
cin >> z;
}
string GetZ()
{
return this->z;
}
};
class B
:public A
{
public:
void use_base(A* k)
{
cout << "here and now, i'm using " << k->GetZ() << " however i, " << this->GetZ() << ", might want to!";
}
};
class C
:public B
{
void use_base(A* k)
{
cout << "extra";
}
};
int main()
{
A Bob;
B Mark;
Bob.SetZ();
Mark.SetZ();
C Karl;
Mark.use_base(&Karl); // doesn't show any error
return 0;
}`
If B inherits publicly from A, then B* can be implicitly converted to A* so a function that takes A* can be called with B* arguments. To prevent this, you could make the inheritance protected or private. However, that might create other problems.
To prevent accidentally passing a B*, you can declare another overload that takes B* and delete it. This overload will win for B* and C* arguments and cause a compilation error. You can also generalize this approach using templates, and so prevent passing a pointer to any class derived from A, without naming all such classes.
void use_base(A* k) { /* do something */ }
void use_base(B*) = delete;
However, that doesn't stop someone from explicitly casting a B* or C* to A* and calling the A* overload.

C++ Have two child classes share a variable from their base class

So say I have 3 classes: Base, A, and B.
Base is a base class for both class A and class B.
Base has a variable val that A and B can access.
How would I get it to work where I can set the val variable through class A, and it is reflected in class B?
For example:
I know this code below won't work because I am creating an OBJECT of the type a and b.
What I want to do is to simply have a and b share the same variable so that whenever a does something to it, it is reflected in b.
a aa;
b bb;
aa.SetVal(50000);
cout << aa.GetVal() << endl;
cout << bb.GetVal() << endl;
In the end I'd want both cout lines to print out 50000.
EDIT: The classes A and B will be doing different operations and just need to be able to access/change the val variable in base
You could make the member a static member of the base class, then all derived classes could access it, however any object of a derived that changes the static member would change it for every other object.
class Base
{
public:
int GetVal()
{
return val;
}
void SetVal( int newVal )
{
val = newVal;
}
private:
static int val;
};
// Need to instantiate the static variable somewhere
int Base::val = 0;
class A : public Base
{};
class B : public Base
{};
class Base {
static int value;
public:
virtual ~Base() { }
void setVal(const int& val) {
value = val;
}
int getVal() const {
return value;
}
};
int Base::value = 0;
class A : public Base {
};
class B : public Base {
};
#include <iostream>
int main() {
A a;
B b;
a.setVal(20);
std::cout << b.getVal(); // 20
}
That's a job for references, not for classes. Just have one class X and create a reference to the object:
X aa;
X& bb = aa;
aa.SetVal(50000);
std::cout << aa.GetVal() << std::endl;
std::cout << bb.GetVal() << std::endl;
The output will be:
50000
50000
Remember to always use the right tool for the job and keep things simple.
The main goal is that those two classes will be doing different things but will need to be able to access and share a single variable.
An idea to solve this is to extract the common variable in another class, namely S, which will be passed to A and B like this:
std::shared_ptr<S> s = new S();
A aa(s);
B bb(s)
Now, both aa and bb share the same S object and can modify it very easily. Notice that the constructor of both A and B should store the std::shared_ptr<S> as well:
class A { // and B
private:
std::shared_ptr<S> s;
public:
A(std::shared_ptr<S> as) : s(as) {}
};
The variable s will last as long as any of aa and bb is alive: when both aa and bb gets deallocated or go out of scope, the variable s will be deallocated as well.
If the type of the common variable should be on the stack, you can also just use references, but watch out for the lifetime of aa, bb and that variable:
int s = 0;
A aa(s);
B bb(s);
with:
class A { // and B
private:
int& s; // or any other type
public:
A(int& as) : s(as) {}
};
But as a general rule of thumb I'd avoid shared state between objects. Most of the time, depending on the context, you can refactor your code and get rid of the shared dependency.
If the shared value is static in the base class, then all instances of derived classes will see exactly that one base class member.
If the value is not static, then each instance of a class will have its own copy whether or not the value is in a base class.
Not sure I understand what you are trying to do. Do you want all instances of A and B to share the same value? if so, declare it as static in the base class.
if not, how do you want to choose which one will share the value?

set the base object of derived object?

This is a basic concept question. If I have a class that Derived that inherits from Base, and I instantiate a new Derived object, can I set it's Base object to a specific Base object of my choosing so that all calls base class methods are redirected to this particular base object?
something like this:
class Base
{
protected:
string name;
public:
Base(string n) { name = n}
void doSomething(){cout << name << "\n";}
};
class Derived : public Base
{
public:
Derived(string n) : Base(n) {}
int main()
{
Derived* d = new Derived("original base"); //create a derived
d->doSomething(); // prints "original base"
Base* rB = new Base("replacement base"); // create a new base object
((Base*) d) = rB; // replace the base object of d with a new one (pretend code)
d->doSomething(); // prints "replacement base"
return 0;
}
I'm sure I made all sorts of errors in that simple code, because my skill level is low, but just for the idea.
Is this possible in C++? We can slice the derived information off of an object, so can we separate and replace the components in a chain of inheritance?
Why would I want to do this?
Consider the mixin lilies: (again, forgive syntax errors)
template <class T> class MyMixin : public T
{
public:
MyMixin(T desiredBaseObject)
{
// do something to set the desired base
// object of this class to desiredBaseObject.
}
};
RandomClass1 dog(int i = 0);
RandomClass2 cat(double i = 0.0);
MyMixin< RandomClass1 > mixin1(dog);
MyMixin< RandomClass2 > mixin2(cat);
In this case, if we could set the base object of the mixin to any desired object, we could use constructors with any parameter list in our mixin without the mixin needing to know anything about it. Also, the mixin could be used like a decorator without the need for a common interface amongst decorators.
Thanks for the answers. Since we can slice off the derived part of an object, it seems like the base and derived information lives separately. Could someone comment on this? Could we access some internal table, like the vtables I hear so much about (I don't know anything about this type of stuff, so maybe this is not applicable), and accomplish this?
#BenoƮt
Could you explain why only 1 and 4 work, but 2 and 3 do not?
class Base
{
protected:
std::string name;
public:
Base(std::string n)
{
name = n;
}
virtual void doSomething()
{
cout << name << "\n";
}
};
class Derived : public Base
{
public:
int x;
Derived(std::string n) : Base(n)
{
x = 5;
}
void printX()
{
cout << "x = " << x << "\n";
x++;
}
};
Derived* d1 = new Derived("original 1");
d1->doSomething();
d1->printX();
Base* rb1 = new Base("new 1");
*static_cast<Base*>(d1) = *rb1;
d1->doSomething();
d1->printX();
cout << "\n\n";
Derived d2 = Derived("original 2");
d2.doSomething();
d2.printX();
Base b2 = Base("new 2");
static_cast<Base>(d2) = b2;
d2.doSomething();
d2.printX();
cout << "\n\n";
Derived d3("original 3");
d3.doSomething();
d3.printX();
Base b3("new 3");
static_cast<Base>(d3) = b3;
d3.doSomething();
d3.printX();
cout << "\n\n";
Derived d4("original 4");
d4.doSomething();
d4.printX();
Base b4("new 4");
*static_cast<Base*>(&d4) = *&b4;
d4.doSomething();
d4.printX();
cout << "\n\n";
this will print:
original 1
x = 5
new 1
x = 6
original 2
x = 5
original 2
x = 6
original 3
x = 5
original 3
x = 6
original 4
x = 5
new 4
x = 6
Why does this only work with when using a pointer?
I'm not questioning why you want to do this, but it's perfectly safe do it unless your inheritance breaks the ISA relationship (eg Derived is a restricted subset of Base, eg a Square is not a Rectangle since it is possible to resize only one dimension of a Rectangle but impossible to do so with a Square).
*static_cast<Base*>(d) = *rB;
(works also with references)
or you can write a little function (you will find lots of functions doing this):
template<typename T>
T& assign(T& to, const T& from)
{
return to = from;
}
assign<Base>(*d, *rB);
and anyway, you do this every time you overload/redefine operator=
Derived& operator=(const Derived& other)
{
// prettier than the cast notation
Base::operator=(other);
// do something specific to Derived;
this->name += " (assigned)";
return *this;
}
No. If you need to do this, you should use composition, not inheritance.
(I'm answering the more general question -- in your specific case where you just want to change the string you can just change name from within the derived class)
Inheritance = IS A relation.
Composition = HAS A relation.
You're describing a class that has an object of type A where you can set its instance.
So you need to use composition - Make a class that hold a member of type A
Inheritance is a property of types, not of objects. The type "Derived" inherits from the type "Base". You can make objects of type "Derived" (Derived x;), and you can also make objects of type "Base" (Base y, unless that's forbidden), but each of those objects are complete, fully-fledged objects with no "replaceable parts".
The point of type inheritance is that you may treat an object of type "Derived" as if it was an object of type "Base" (as long as you refer to it by reference or pointer), that is, if you have a function void foo(Base & b);, then you may call foo(x). But foo can only access those parts of x which are inherited from "Base"!
You could combine inheritance & composition:
class A {
string name;
public: A(const char* s) : name(string(s)) {}
virtual void m() { cout << name << endl; }
};
class B : A {
public:
B(const char* s) : A(s), a(0) {}
void m() { if (a) a->m(); else A::m(); }
A* a;
};
int main() {
B b("b");
b.m(); // prints b
b.a = new A("a");
b.m(); // prints a
}
No, you cannot do that.
You have (at least) a couple of options:
Create a new Derived object, parameterised by a mixture of parameters from the two objects you wish to combine.
Create some setter methods in the Base class, that allow you to change its parameters/state later in its lifetime.
No.
Why would you want to do this? If two Deriveds are supposed to have the exact same Base, such that modifications through one Derived show up in the other, you need to have some sort of pointer to Base in each derived, making this composition, not inheritance.
If you want to change the data in the Derived's Base, write a function to do that, a little like a copy assignment operator for Base.
Alternately, you could make a new constructor for Derived that would take a Base and a Derived, and take Base information from the Base and Derived information from the Derived.

Override or remove an inherited constructor

Here is some C++ code:
#include <iostream>
using namespace std;
class m
{
public:
m() { cout << "mother" << endl; }
};
class n : m
{
public:
n() { cout << "daughter" << endl; }
};
int main()
{
m M;
n N;
}
Here is the output:
mother
mother
daughter
My problem is that I don't want the m's constructor to be called when I create N. What should I do ?
AFAIK, you cannot remove inherited constructor.
The problem in your example comes from incorrect class design.
Constructor is normally used for allocating class resources, setting default values, and so on.
It is not exactly suitable to be used for outputting something.
You should put
n() { cout << "daughter" << endl; }
Into virtual function.
In general - if you have a need to remove inherited constructor, then you probably need to rethink/redesign your class hierarchy.
class m
{
public:
m(bool init = true) { if (init) cout << "mother" << endl; }
};
class n : m
{
public:
n() : m(false) { cout << "daughter" << endl; }
};
or if you don't want it to be public
class m
{
protected:
m(bool init) { if(init) Init(); }
Init() { cout << "mother" << endl; }
public:
m() { Init(); }
};
class n : m
{
public:
n() : m(false) { cout << "daughter" << endl; }
};
Two solutions:
Don't derive n from m. Check that you really have interface reuse (that you rely on a polymorphic interface) instead of implementation reuse. In the latter case, prefer making an m* a member of n and then only create the m object when needed. This would be my preferred solution.
You probably don't want ms contructor to be called because it does something which you don't want. Move that code which you don't want to execute out of ms constructor into a dedicated init() function or the like, and then call it as needed. I don't recommend this because you end up with a stateful interface.
Constructors are never inherited. What happens is that C++ generates a default nullary constructor that initializes the base classes and members of class type. The base classes are always initialized and there is no way to prevent this, so if you don't want the base class constructors to be called, don't inherit from the base class.
Object of any class contains in it sub-objects of all its superclasses. And all of them must be constructed before construction of main object. Part of this construction is calling one of base class constructors and it cannot be omitted. You can only choose constructor to be called.