Calling constructor of potential child from base in C++ - c++

How can someone implement this pattern:
class Base {//doesn't know anything about potential descendant-classes, like Child
public:
Base * foo( void) {
//some code
return ( Base *) new !Child-constructor!();
}
};
class Child : public Base { };
//—————————————————————————————————————————————————
#include <iostream>
#include <typeinfo>
using namespace std;
int main( void) {
Base * base_p = Child().f();
cout << typeid( *base_p).name(); //expected to get "Child"
return 0;
}
I can't find the right syntax for this type of constructions (calling the "potential" child constructor).
UPD: I forgot to mention (didn't think that there can be missunderstanding), that Child class must not be known in definition of Base. So I wanted foo to call the constructor of the class in which it's gonna be inherited.

"... that Child class must not be known in definition of Base. So I wanted foo to call the constructor of the class in which it's gonna be inherited."
IMHO the easiest way is to provide a templated factory function with Base
class Base {
public:
template<class Derived>
static std::unique_ptr<Base> foo( void) {
//some code
return std::unique_ptr<Base>(new Derived());
}
};
class Child : public Base {
public:
Child() {}
virtual ~Child() {}
};
int main() {
std::unique_ptr<Base> p = Base::foo<Child>();
return 0;
}
Check the compilable sample here please.

This design is awful, btw.
//terriblecode.hpp
struct Base
{
Base * foo(void);
};
struct Child : public Base{};
//terriblecode.cpp
Base* Base::foo() {return (Base*) new Child();}
The definition of child isn't needed untill the definition of foo. Separate your declaration from your definition of member functions, and it is pretty easy to do.

Just need to make sure you let the compiler know about your derived class before the first use:
class Child; // forward declaration
class Base {
public:
Base * foo( void);
};
class Child : public Base { };
// the function needs to be defined after the "Child" is known
Base * Base::foo( void) {
//some code
return new Child; // will be automatically type-cast to base class
}
//—————————————————————————————————————————————————
#include <iostream>
#include <typeinfo>
using namespace std;
int main( void) {
Base * base_p = Child().f();
cout << typeid( *base_p).name(); //expected to get "Child"
return 0;
}
However, I'd recommend a different pattern:
class Child; // forward declaration
class Base {
public:
static Base * foo( void); // static "factory" method
};
class Child : public Base { };
// the function needs to be defined after the "Child" is known
Base * Base::foo( void) {
//some code
return new Child; // will be automatically type-cast to base class
}
//—————————————————————————————————————————————————
#include <iostream>
#include <typeinfo>
using namespace std;
int main( void) {
Base * base_p = Base::f(); // use scope resolution, not object's method
cout << typeid( *base_p).name(); //expected to get "Child"
return 0;
}

Related

How to deduce type of a derived class

Lets say I have a base abstract class:
class Base
{
public:
virtual ~Base(){};
};
and derived from it template class:
template<typename T>
class Derived : public Base
{
public:
void function();
};
And another class Test, which has vector of Base class objects
class Test
{
public:
vector< Base* > base_vector;
};
QUESTION 1: If we have a vector of pointers to objects of Base class, they can also be filled with pointers to Derived classes, right?
So, lets say now I access this vector from already existing test class, which was previously filled with pointers to objects of Derived class type
void (Test test)
{
vector<Base*> objects = test.base_vector;
}
QUESTION 2: Is it possible to deduce the typename of the Derived objects, which pointers point to? (Derived class is a template)
OR Is it possible to call function() which was defined in Derived class, and dont care about type of the Derived class ?
If not, what are the minimal changes that should be made to any of these classes?
If I understand your problem correctly then you need to use virtual functions. If you want to call a function on the objects and make sure that the function of the correct type is called then make your function virtual. So you need to declare it in your Base class. Also, you need to make your vector be a vector of pointers to Base. Then when you call your function on the objects of the vector it will call the function from the derived class if the objects are indeed of the derived type.
This way you don't need to find out the type of the objects, you'll just call the virtual function and it will find out what type of object it is and call the correct function.
I'm not sure that I understood what you want, but will this modification of your code work for you? This way you either do not need to deduce type at all, or you can get a virtual type() method, that will return you an enum with some unique value for every type.
#include <memory>
#include <string>
#include <vector>
#include <iostream>
class Base {
public:
virtual void function() = 0;
virtual ~Base() = default;
};
template <class T> class Derived : public Base {
public:
void function() override {
// to produce some output
std::cout << typeid(T).name() << std::endl;
}
};
class Test {
public:
std::vector<std::unique_ptr<Base>> objects;
};
int main() {
Test test;
test.objects.push_back(std::make_unique<Derived<int>>());
test.objects.push_back(std::make_unique<Derived<std::string>>());
for (auto &ptr : test.objects) {
ptr->function();
}
}
Alternative solution to this problem is to use a variant class, for example boost::variant, or std::experimental::variant (if you standard library already has one). This way you don't need to have virtual function() in Base class. boost::variant has which() method that returns you and integer number of type in a type list. An example:
#include <boost/variant.hpp>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
class Base {
public:
virtual ~Base() = default;
};
template <class T> class Derived : public Base {
public:
void function() {
std::cout << typeid(T).name() << std::endl;
}
};
class Test {
public:
std::vector<boost::variant<Derived<int>, Derived<std::string>>> objects;
};
int main() {
Test test;
test.objects.push_back(Derived<int>());
test.objects.push_back(Derived<std::string>());
for (auto& obj : test.objects) {
switch (obj.which()) {
case 0:
boost::get<Derived<int>>(obj).function();
break;
case 1:
boost::get<Derived<std::string>>(obj).function();
break;
}
}
return 0;
}

Is it possible to create an instance of a class within the same class?

Say I have a class:
class Foo{
public:
Foo(){
}
//Is it possible to create a function like this:
virtual Foo* createOb(){
//Should create a new Foo,Bar or Fiz, depending on the actual object type.
}
}
class Bar: public Foo{
public:
Bar(){
}
}
class Fiz: public Foo{
public:
Fiz(){
}
}
Is it possible to have a method createOb() in the base class, so when createOb() is called on an instance of one of the derived classes, that an instance of the derived class is created ?
Yes, it can be done, using CRTP.
Bu first, returning a raw pointer obtained from new is very dangerous. In c++ raw pointers should be used only when they do not have ownership of the pointed object. So I took the liberty to use unique_ptr:
struct Base {
virtual auto create_obj() -> std::unique_ptr<Base>
{
return std::unique_ptr<Base>{};
}
};
// abstract works too:
struct Base {
virtual auto create_obj() -> std::unique_ptr<Base> = 0;
};
template <class Derived>
struct Base_crtp : Base {
auto create_obj() -> std::unique_ptr<Base> override /* final */
{
return std::unique_ptr<Base>{new Derived{}};
}
};
struct D1 : Base_crtp<D1>
{
};
struct D2 : Base_crtp<D2>
{
};
And then:
auto b1 = std::unique_ptr<Base>{new D1{}};
auto b2 = std::unique_ptr<Base>{new D2{}};
auto new_d1 = b1->create_obj();
auto new_d2 = b2->create_obj();
Definitely YES!!!
When a method is declared virtual in base class, and called through the derived class object, then the derived class function gets called (Read vprt, vtable concept in c++).
#include <iostream>
using namespace std;
class A{
public:
virtual A* getobj(){
return new A();
}
};
class B: public A{
public:
B(){cout<<"B constructor"<<endl;}
virtual A* getobj(){
return new B();
}
};
int main()
{
A *a = new B();
A *second = a->getobj();
return 0;
}
In the above code, we are calling the getobj() function using class B's object.
Here the constructor of class B is called twice.
first, for new B() in main
secondly for getobj function call which again creates object of B
This is not an optimal solution, but it works.
In your .h
class Foo{
public:
Foo();
virtual Foo* createOb();
};
class Bar: public Foo{
public:
Bar();
};
class Fiz: public Foo{
public:
Fiz();
};
In your .cpp
#include "Header.h"
Foo::Foo() {}
Foo* Foo::createOb(){
if (dynamic_cast<Bar*>(this)) {
return new Bar();
}
else if (dynamic_cast<Foo*>(this)) {
return new Foo();
}
return nullptr;
}
Bar::Bar() {}
Fiz::Fiz() {}
As already suggested please consider a pure virtual method
No, this is not possible with "pure" inheritance. The classes must override createOb() member function in order to support cloning.
You can see why this is not possible by considering separate compilation of classes. An implementation of one-fits-all createOb() member function must be completed in isolation from Bar and Fiz, making it impossible for the base to know the type of its subclasses.
An implementation with a pure virtual function in the base is very common, though.
Another approach is to use Curiously Recurring Template Pattern (CRTP) to implement cloning. This article explains how it can be done.

Base class method alias

Let's consider the following code:
#include <iostream>
class Base
{
public:
void foo() //Here we have some method called foo.
{
std::cout << "Base::foo()\n";
}
};
class Derived : public Base
{
public:
void foo() //Here we override the Base::foo() with Derived::foo()
{
std::cout << "Derived::foo()\n";
}
};
int main()
{
Base *base1 = new Base;
Derived *der1 = new Derived;
base1->foo(); //Prints "Base::foo()"
der1->foo(); //Prints "Derived::foo()"
}
If I have the above stated classes, I can call the foo method from any of Base or Derived classes instances, depending on what ::foo() I need. But there is some kind of problem: what if I need the Derived class instance, but I do need to call the Base::foo() method from this instance?
The solve of this problem may be next:
I paste the next method to the class Derived
public:
void fooBase()
{
Base::foo();
}
and call Derived::fooBase() when I need Base::foo() method from Derived class instance.
The question is can I do this using using directive with something like this:
using Base::foo=fooBase; //I know this would not compile.
?
der1->Base::foo(); //Prints "Base::foo()"
You can call base class method using scope resolution to specify the function version and resolve the ambiguity which is useful when you don't want to use the default resolution.
Similar (Not exactly same case) example is mentioned # cppreference
struct B { virtual void foo(); };
struct D : B { void foo() override; };
int main()
{
D x;
B& b = x;
b.foo(); // calls D::foo (virtual dispatch)
b.B::foo(); // calls B::foo (static dispatch)
}

trying to call protected function of parent class in child class in c++ [duplicate]

This question already has answers here:
accessing a protected member of a base class in another subclass
(8 answers)
Closed 7 years ago.
I always thought that I understood inheritance, but obviously I don't. I would like to call a protected member function of another instance of the same parent class from a child class like in the following example code:
#include <iostream>
class Parent {
protected:
void doStuff(){
std::cout << 5 << std::endl;
}
};
class Child : public Parent {
public:
void pubfunc(Parent* p){
p->doStuff();
}
};
int main(){
Child* c = new Child();
Parent* p = new Parent();
c->pubfunc(p);
return 0;
}
However, compilation of this code fails with:
In member function ‘void Child::pubfunc(Parent*)’:
error: ‘void Parent::doStuff()’ is protected
error: within this context
I wouldn't want to make the Child class a friend of the Parent class to avoid forward declarations and forward includes of child classes as much as possible. Also, I don't want to make doStuff public, because it can really mess up the internal structure of Parent when used in the wrong circumstances.
Why does this error happen, and what is the most elegant way to solve it?
Mostly the problem is that if C++ allowed you to access the non-public members of the referent of a base class pointer directly, then you could gain easy access to the data of an object simply by deriving from a common base.
Still this is a known loophole in the C++ type system, as shown below, where you can gain that access without modifying the base class, and without using casts or anything like that.
On the third and gripping hand, what you should do is to support the intended usage directly in the base class, by adding a static member function there, as follows:
#include <iostream>
using namespace std;
class Base
{
protected:
void doStuff()
{
cout << 5 << endl;
}
static void doStuff( Base* p ) { p->doStuff(); }
};
class Derived : public Base
{
public:
void pubfunc( Base* p )
{
doStuff( p );
}
};
auto main() -> int
{
Derived d;
Base b;
d.pubfunc( &b );
}
In my humble opinion this is most clear and elegant.
But for completeness, the type system loophole:
#include <iostream>
using namespace std;
class Base
{
protected:
void doStuff()
{
cout << 5 << endl;
}
};
class Derived : public Base
{
public:
void pubfunc( Base* p )
{
(p->*&Derived::doStuff)();
}
};
auto main() -> int
{
Derived d;
Base b;
d.pubfunc( &b );
}
I recommend the static member function, though.
Protected members are accessible in the class that defines them and in classes that inherit from that class. Sometimes it causes people to be confused when they see this kind of errors. But in fact you call doStuff function for Parent object, it doesn't meter if function call done inside inherited class. The result will be the same if you call doStuff function from main().
class Parent
{
protected:
virtual void doStuff()
{
std::cout << 5 << std::endl;
}
};
class Child : public Parent
{
protected:
void doStuff() override
{
std::cout << 8 << std::endl;
}
public:
void pubfunc(Parent* p)
{
((Child*)p)->doStuff();
}
};
int main()
{
Child* c = new Child();
Parent* p = new Parent();
c->pubfunc(p); // will print 5
c->pubfunc(c); // will print 8
return 0;
}

Tell compiler about subclass -polymorphism

If I have a baseclass Base and a subclass Sub, and in the subclass have a memberfunction that doesnt exist in the superclass - how do I tell the compiler its there?
#include <iostream>
using namespace std;
class Base {
public:
};
class Sub : public Base {
public:
void printFromSub() {
cout << "I am not inherited ;-)" << endl;
}
};
int main() {
Sub sub;
Base* base;
base = ⊂
base->printFromSub(); // not possible at compile-time
return 0;
}
You have to cast to derived class.
If you are sure that base points to an object of the derived class, then you can use static_cast.
static_cast<Sub*>(base)->printFromSub();
If you aren't sure, then you'll need a runtime check.
Sub* p = dynamic_cast<Sub*>(base);
if (p) p->printFromSub();