sealed class implementation query - c++

I was reading the C++ faqs on http://www2.research.att.com/~bs/bs_faq2.html , when i came accross this code to implement a 'sealed' class:
class Base{
public:
friend class A;
private:
Base(){cout<<"Base constructor called";}
};
class A : public virtual Base{
public:
A(){cout<<"A const called";}
};
class B : private A{};
int main(){
A a;
//B b;
return EXIT_SUCCESS;
}
I did not understand how by using the virtual keyword, 'sealed' class effect is achieved. If i remove the virtual keyword, then it has no 'sealed' effect. Why?

It works because due to the way virtual inheritance works, B must construct Base- which it can't, because Base's constructor is private. Only A can construct Base. In normal inheritance, B constructs A, which constructs Base, which is fine because A can construct Base and B can construct A.

Related

Passing the derived class constructor parameter to a protected member

I'm trying to practice some polymorphism and i got into some issues.
Here's my code :
class A{ //the base
public:
A(){}
virtual void Log(){};
virtual ~A(){};
private:
protected:
int __value;
};
class B : public A{ //the derived
public:
B(int value):__value(value){} //here's the problem
void Log() override{
std::cout<<__value<<"\n";
}
~B(){};
};
At that lines the error said : "class 'B' does not have any field named '__value'". It does work if i will do it in this way :
class A{
public:
A(){}
virtual void Log(){};
virtual ~A(){};
private:
protected:
int __value;
};
class B : public A{
public:
B(int value){
__value=value;
}
void Log() override{
std::cout<<__value<<"\n";
}
~B(){};
};
I know what i've tried works while i'm accesing the private members, but I want to know if there is some way to make the first attempt work too.
Thanks!
C++ does not work this way. Only a class's constructor can initialize its members.
Only A's constructor can initialize its class member. That's what a constructor's job is. A derived class cannot initialize its base class's members, only it's own class members. A base class only initializes the base class's members. A derived class's constructor can initialize only its own class's members.
What you need to do is add a constructor to A, perhaps a protected constructor, with a parameter that initializes the class member with the parameter:
class A {
// ...
A(int value) : __value{value} {}
// ...
};
And have the derived class's constructor explicitly invoke this constructor.
B(int value) : A{value}
{
}
In some situations you can also delegate the constructor, as an alternative. This should be covered in the advanced C++ chapters of your C++ book.
P.S. You should use modern C++'s uniform initialization syntax, with {...} instead of (...). If you're using an older C++ book that doesn't cover uniform initialization syntax, you should get a more recent book.

Inheritance in C++: define variables in parent-child classes

Problem
I am looking for the best way to define the variables in parent-child classes, in order to be called by a pointer to their parent class.
This is the protocode:
class Base {
public:
virtual void function() = 0;
};
class A : public Base {
public:
int a, b;
A(int a_, int b_) : a(a_), b(b_) {};
void function() { // do something.. }
};
class B : public Base {
public:
int a, b;
B(int a_, int b_) : a(a_), b(b_) {};
void function() { // do something.. }
};
Base* elements[2] = {
new A(1,2),
new B(3,4)
};
Since I define a, b in both constructors, I might define them in the abstract class Base. This way the code should be more efficient and clean. Is this practice correct? How should I define them?
Possible solutions
The solution I have in mind is implementing a function that returns for example a like this:
class Base {
public:
virtual int return_a() = 0;
};
class A : public Base {
public:
int a, b;
A(int a_, int b_) : a(a_), b(b_) {};
int return_a() {
return a;
}
};
int main(){
int a = elements[0]->return_a();
}
This works, but I am sure it is not an efficient way. Is it better to define a, b in the abstract class? Thanks
Is this practice correct?
I think this is turning into an opinion-based question-answer. If all your derived classes must include the members a and b, then in my opinion, they should be part of the base class. This way, you are guaranteed that all your derived classes will include the members a and b and you (or someone else) won't run the risk of forgetting to include them. Furthermore, by including the members in the base class, you save memory by not having to include them at every single derived class. C++'s virtual provides you with all the necessary tools to accomplish polymorphism, which is what happens when you create an array of Base *.
I would also recommend you use the keyword override for the virtual functions that are overridden in the derived class, and the keyword final for the derived classes that are not meant to become base classes. You can read the benefits of using those keywords from Scott Meyers Modern C++ book.
struct Base
{
int a, b;
Base(int a_, int b_) : a(a_) , b(b_)
{;}
virtual void function() = 0;
};
struct A : Base // A can be a base class of another class.
{
A(int a_, int b_) : Base(a_,b_)
{;}
void funtion() // this will compile, but it's not going to override the Base::function()
{;}
};
struct B final : Base // B can never become a base class.
{
B(int a_, int b_) : Base(a_,b_)
{;}
void funtion() override // this won't compile because override will see that we mis-spelled function()
{;}
};
However, there is no C++ rule that prohibits you from including the members in all of your derived classes.
Also, if all your members are public, then you can use a struct to avoid having to type public inside the classes and in the inheritance method.
struct Base
{
// all members are public
};
struct Derived : Base // public inheritance by default.
{
// all members are public
};
This is somewhat opinion based, but here is what I think based on the code you have posted.
Since you have made Base (from which all classes are derived) an abstract class, it appears that you want to use it as an interface.
In that case, it is better to distinguish between interface inheritance and implementation inheritance. Let Base not have any data which means that it would not require any constructors.
This is one of the coding guidelines given by Bjarne Stroustrup titled: When designing a class hierarchy, distinguish between implementation inheritance and interface inheritance.
The reason given is:
Implementation details in an interface make the interface brittle; that is, make its users vulnerable to having to recompile after changes in the implementation. Data in a base class increases the complexity of implementing the base and can lead to replication of code.
Note that you do not need getters or setters if the data in derived classes is public.

store abstract member, keep interface simple

I know that it is not possible to have an instance of an abstract class as a base member of another class, i.e.,
#include <iostream>
class Base {
public:
Base() {};
virtual ~Base() {};
virtual int yield() = 0;
};
class C1: public Base {
public:
C1(): Base() {};
virtual ~C1() {};
virtual int yield() {return 1;};
};
class D {
public:
D(Base & b): b_(b) {};
virtual ~D() {};
private:
Base b_;
}
int main() {
C1 c;
D d(c);
}
will fail to compile with the error
test.cpp:22:10: error: cannot declare field ‘D::b_’ to be of abstract type ‘Base’
The obvious workaround is to use (shared) pointers instead. This, however, makes main somewhat more complicated to read,
int main() {
auto c = std::make_shared<C1>();
D d(c);
}
which I would really like to avoid.
Is there a way to keep the main file as simple as in the above example and still achieve the desired functionality?
You can't. When you are creating D it allocates (in heap or in stack) memory for B. And C1 class needs size of base class B plus size of extra variables/etc in C1 itself even if there are nothing new.
So, use pointers instead.
The error caused by virtual int yield() = 0;. If you use virtual int yield(), it will works. When you used virtual int yield() = 0;, it said that the function is a pure virtual function, so you must override it. So you should give its inheritance class and use the instance of inheritance class in class C1. In a world, virtual int yield() = 0; only remind you that it is only a interface, you must override it. I hope this can help you.
Since Base is an abstract class (has at least one pure virtual function), it can't be instantiated directly.
When you declare D's class member as "Base b_", you are effectively trying to create an instance. You can instead use a pointer there (or some kind of safe/smart pointer).
#include <iostream>
class Base {
public:
Base() {};
virtual ~Base() {};
virtual int yield() = 0;
};
class C1: public Base {
public:
C1(): Base() {};
virtual ~C1() {};
virtual int yield() {return 1;};
};
class D {
public:
D(Base * b): b_(b) {};
virtual ~D() {};
private:
Base *b_; // Use a pointer or safe ptr or something of that sort.
}
int main() {
C1 c;
D d(&c);
}
No. One of the properties of an abstract class is that it cannot be instantiated. That means an instance of an abstract class cannot be a member of another class.
Even if Base was not abstract, your class D's constructor would be slicing the object passed. If passed an instance of C1, the copying (in the initialiser list of D's constructor) would not magically cause an instance of D to contain an object of type C. It would instead create a copy only of the Base part of that object.
In short, your design is broken, and will not work even if - syntactically - it would be possible to simplify the code in main().

C++ issue with polymorphism base and inherited class instantiation

I have a basic base class and a couple of sub-classes which inherit from it.
Class Base{
public:
Base(){};
virtual ~Base();
virtual void foomethod()=0; //Marked as pure virtual
};
Class A : public Base{
A(){}; //Ctor
~A(){}; //Dtor
void foomethod(){ /* DO SOMETHING */ }
}
Class B : public Base{
B(){}; //Ctor
~B(){}; //Dtor
void foomethod(){ /* DO SOMETHING */ }
}
Use of the above is throwing an error in the following usage:
Base a = A();
Base b = B();
The compiler is complaining about the function foomethod() being pure virtual.
However, when the following is used, there is no problem.
A a = A();
B b = B();
I would have thought that the first instance should be accepted due to C++'s principles of polymorphism. I want to enforce a specific method implementation of the method in sub-classes. If it is marked as virtual only, there is not guarantee that it will be explicitly overrided.
There are several issues with your code, I'll try to get most of them:
You can't have a pure function without marking it as virtual
You can't create objects of an abstract Base class (there's no code for the methods)
When you write
Base b = A();
you're creating two objects and then assigning the A object to the Base b object. This cannot happen since Base is abstract but in cases where this can happen you could experience the slicing problem.
You marked the destructor as virtual in the derived classes but not in the Base (and no definition either), always mark it as virtual when using virtual polymorphism otherwise derived destructors will not be called
This is a more correct way of doing it:
#include <iostream>
using namespace std;
class Base{
public:
Base(){};
virtual ~Base() {};
virtual void foomethod()=0; //Marked as pure virtual
};
class A : public Base{
public:
A(){}; //Ctor
virtual ~A(){}; //Dtor
void foomethod(){ cout << "Hello from A"; }
};
class B : public Base{
public:
B(){}; //Ctor
virtual ~B(){}; //Dtor
void foomethod(){ /* DO SOMETHING */ }
};
int main() {
// Base obj; // Can't do that
Base *obj = new A();
obj->foomethod(); // A's one
delete obj;
return 0;
}
http://ideone.com/gvcL9S
Oh and there were some syntax errors here and there.. and a visibility problem if you intend to use those functions from the outside.. but I believe the excerpt was just a pseudocode one.

c++ derived class with private access specifier

I have a derived class (class B) from a base class (class A). Class A has a protected virtual function foo() which I want to override and use it as private in derived class.
Class A{
protected:
virtual void foo() = 0;
}
I am wondering whether the following
Class B: public Class A
private:
virtual void foo();
and
Class B: private Class A
private:
virtual void foo();
are the same.
They are not the same. In the first example, B is-an-A, in the second it isn't. So in the first case you can have code such as
void foo(const A& a);
which accepts A and B as arguments. With private inheritance, you could not do that. For example,
A a;
B b;
foo(a); // OK with private and public inheritance
foo(b); // OK only with public inheritance, i.e. B is an A.
No, your two cases are not the same.
In the second case class B can't be casted to class A, because a private base class is hidden. in this aspect would get the same behavior as if class A would be a member of class B.
No both are not same
In public inheritance class A's foo() will be protected member in class B
In private inheritance class B can only access the public members of the class A so there will not present any foo() of class A in class B.