I have class that inherits from a base class. The base class contains pure virtual functions that are overridden in the derived class. I instantiate the base class object with std::unique_ptr of the derived class but get a compile time error
class Base {
public:
~Base () = default;
initBase () { count = 0; }
virtual void method1() = 0;
virtual void method2() = 0;
private:
int count;
};
class Child final : public Base {
public:
Child() = default;
~Child() = default;
void method1() override { std::cout << "B Running method 1\n"; }
void method2() override { std::cout << "B Running method 2\n"; }
};
class myClass {
public:
myClass(std::unique_ptr<Base> base) { _base(std::move(base)) };
~myClass() = default();
private:
std::unique_ptr<Base> _base;
};
int main() {
myClass obj = myClass(std::make_unique<Child>());
}
Compiler gives the following error:
error: invalid new-expression of abstract class type 'Base'
{ return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); }
because the following virtual functions are pure within 'Base':
class A {
'virtual void Base::method1()'
virtual void method1() = 0;
'virtual void Base::method2()'
virtual void method2() = 0;
There are several typos in your code:
In Base:
Change
initBase () { count = 0; }
to
Base () { count = 0; }
In Child:
change
myClass(std::unique_ptr<Base> base) { _base(std::move(base)) };
to
myClass(std::unique_ptr<Base> base) : _base(std::move(base)) { }
change
~myClass() = default();
to
~myClass() = default;
In main():
change
myClass obj = myClass(std::make_unique<Child>());
to
myClass obj(std::make_unique<Child>());
#include <iostream>
#include <memory>
class Base {
public:
~Base () = default;
Base () { count = 0; }
virtual void method1() = 0;
virtual void method2() = 0;
private:
int count;
};
class Child final : public Base {
public:
Child() = default;
~Child() = default;
void method1() override { std::cout << "B Running method 1\n"; }
void method2() override { std::cout << "B Running method 2\n"; }
};
class myClass {
public:
myClass(std::unique_ptr<Base> base) : _base(std::move(base)) { }
~myClass() = default;
private:
std::unique_ptr<Base> _base;
};
int main() {
myClass obj(std::make_unique<Child>());
std::cout << "OK";
}
With those fixes in place, the code compiles fine.
Live Demo
Related
In the virtual method create() in the derived class Derived, I return a struct of type HelpDerived. However, since I had to set the return type of the method to HelpBase, I found that I need to cast the returned object back to the type HelpDerived.
The following is an example of my case.
#include <iostream>
struct HelpBase {
int a = 0;
virtual void output() {}
};
struct HelpDerived : HelpBase {
int b = 0;
void output() override {}
};
class Base {
public:
virtual HelpBase create() = 0;
};
class Derived : public Base {
public:
HelpBase create() override;
};
HelpBase Derived::create() {
HelpDerived d;
d.a = 1;
d.b = 2;
return d;
}
int main() {
Derived d;
auto based = d.create();
HelpDerived derived = dynamic_cast<HelpDerived &>(based);
std::cout << derived.a << std::endl;
}
When I run the code abve, I get the error
terminate called after throwing an instance of 'std::bad_cast'
what(): std::bad_cast
Abort trap: 6
What have I misunderstood about objects and casting in C++? Why does this method not work?
What can I do to fix the problem?
I think you'd better return a pointer to avoid object slicing in your create function.
#include <iostream>
struct HelpBase {
int a = 0;
virtual void output() {}
};
struct HelpDerived : HelpBase {
int b = 0;
void output() override {}
};
class Base {
public:
virtual HelpBase* create() = 0;
};
class Derived : public Base {
public:
HelpBase* create() override;
};
HelpBase* Derived::create() {
HelpDerived* d = new HelpDerived;
d->a = 1;
d->b = 2;
return d;
}
int main() {
Derived d;
auto based = d.create();
HelpDerived* derived = dynamic_cast<HelpDerived *>(based);
std::cout << derived->a << " " << derived->b << std::endl;
delete derived;
}
I've replaced dynamic cast by static cast and it worked for me almost fine.
#include <iostream>
struct HelpBase {
int a = 0;
virtual void output() {}
};
struct HelpDerived : HelpBase {
int b = 0;
void output() override {}
};
class Base {
public:
virtual HelpBase create() = 0;
};
class Derived : public Base {
public:
HelpBase create() override;
};
HelpBase Derived::create() {
HelpDerived d;
d.a = 3;
d.b = 2;
return d;
}
int main() {
Derived d;
auto based = d.create();
HelpDerived derived = static_cast<HelpDerived &>(based);
std::cout << derived.a << std::endl;
std::cout << derived.b << std::endl;
}
Output:
3
32726
Note that a value is correct, while b is junk. This is because for derived constructor has not been called.
In general, casting from base class to derived is not recommended, as derived may have more data members, than base class.
Recommended reading: https://www.bogotobogo.com/cplusplus/upcasting_downcasting.php
I am learning a design pattern, vistor pattern, in c++.
At first, I copy my two practice codes below. First one is "my test code", and the second one is a simplified code of "normal visitor pattern" in my text book. I would like you to read the first code but the second one is just a reference code of normal visitor pattern.
My question is why visitor pattern asks each class to inherit VisitorsHostInterface class which has virtual function, accept(); please refer to the second code, "normal visitor pattern", below if necessary. In my understanding, it is not necessary to use accept() function to scan all instances, like the first code, "my test code".
I suppose "my test code" is simpler than "normal visitor pattern".
Please tell me the reason why visitor pattern asks accept() function to each class? Thank you very much.
(1) my test code
class ClassD;
class ClassC {
public:
ClassC(int new_value, ClassD* new_next_object) : value_(new_value), next_object_(new_next_object) {};
void print() { std::cout << "ClassC value_ = " << value_ << std::endl; }
int value() { return value_; }
std::shared_ptr<ClassD> next_object(void) { return next_object_; }
private:
int value_=0;
std::shared_ptr<ClassD> next_object_;
};
class ClassD {
public:
ClassD(int new_value, ClassC* new_next_object) : value_(new_value), next_object_(new_next_object) {};
void print() { std::cout << "ClassD value_ = " << value_ << std::endl; }
int value() { return value_; }
std::shared_ptr<ClassC> next_object(void) { return next_object_; }
private:
int value_=0;
std::shared_ptr<ClassC> next_object_;
};
class VisitorFuncInterface {
public:
virtual ~VisitorFuncInterface() = default;
virtual void visit(ClassC* obj) = 0;
virtual void visit(ClassD* obj) = 0;
};
class VisitorFunc : public VisitorFuncInterface {
public:
virtual ~VisitorFunc() = default;
void visit(ClassC* obj) {
if (obj) {
obj->print();
this->visit(obj->next_object().get());
}
}
void visit(ClassD* obj) {
if (obj) {
obj->print();
this->visit(obj->next_object().get());
}
}
};
void test_visitor_without_host(void) {
ClassD* d0 = new ClassD(0, nullptr);
ClassC* c0 = new ClassC(1, d0);
ClassD* d1 = new ClassD(2, c0);
VisitorFunc v;
v.visit(d1);
delete d1;
}
The result of test_visitor_without_host() is following,
ClassD value_ = 2
ClassC value_ = 1
ClassD value_ = 0
(2) normal visitor pattern code
class ClassA;
class ClassB;
class VisitorInterface {
public:
virtual ~VisitorInterface() = default;
virtual void visit(ClassA* obj) = 0;
virtual void visit(ClassB* obj) = 0;
};
class VisitorsHostInterface { // = visitor's host
public:
virtual ~VisitorsHostInterface() = default;
virtual void accept(VisitorInterface& v) = 0;
};
class VisitorsHost : public VisitorsHostInterface {
public:
virtual ~VisitorsHost();
void accept(VisitorInterface& v) {};
};
class ClassA : public VisitorsHostInterface {
public:
ClassA(int new_value, ClassB* new_next_object) : value_(new_value), next_object_(new_next_object) {};
void print() { std::cout << "ClassA value_ = " << value_ << std::endl; }
int value() { return value_; }
std::shared_ptr<ClassB> next_object(void) { return next_object_; }
void accept(VisitorInterface& v) { v.visit(this); };
private:
int value_=0;
std::shared_ptr<ClassB> next_object_;
};
class ClassB : public VisitorsHostInterface {
public:
ClassB(int new_value, ClassA* new_next_object) : value_(new_value), next_object_(new_next_object) {};
void print() { std::cout << "ClassB value_ = " << value_ << std::endl; }
int value() { return value_; }
std::shared_ptr<ClassA> next_object(void) { return next_object_; }
void accept(VisitorInterface& v) { v.visit(this); };
private:
int value_=0;
std::shared_ptr<ClassA> next_object_;
};
class Visitor : public VisitorInterface {
public:
virtual ~Visitor() = default;
void visit(ClassA* obj) {
if (obj) {
obj->print();
this->visit(obj->next_object().get());
}
}
void visit(ClassB* obj) {
if (obj) {
obj->print();
this->visit(obj->next_object().get());
}
}
};
void test_visitor(void) {
ClassB* b0 = new ClassB(0, nullptr);
ClassA* a0 = new ClassA(1, b0);
ClassB* b1 = new ClassB(2, a0);
Visitor v;
b1->accept(v);
delete b1;
}
The result of test_visitor() is following,
ClassB value_ = 2
ClassA value_ = 1
ClassB value_ = 0
In your example, you hold all the objects by value and know their static & dynamic type. You don't need dynamic dispatch, so you don't need to have a common VisitorsHostInterface base class. All that's required is for your classes to implement an accept function.
However, the visitor pattern is most commonly used when you don't have access to the dynamic type of the visited objects. Say you have a vecotr<unique_ptr<Widget>>. Where many different Widget sub-types are stored by pointer. Than Widget and every one of its sub classes must implement a virtual accept function. To get to the objects dynamic type, you need to do dynamic dispatch.
I have the current setup:
class Interface1
{
public:
virtual ~Interface1() {}
virtual void DoSomething() = 0;
};
class Interface2 : public virtual Interface1
{
public:
virtual ~Interface2() {}
virtual void DoSomething() override = 0;
virtual void DoSomethingElse() = 0;
};
class MyClass1 : public Interface1
{
public:
MyClass1();
void DoSomething() override;
};
class MyClass2 : public Interface2
{
public:
MyClass2();
void DoSomething() override;
void DoSomethingElse() override;
};
int main()
{
std::map<std::string, boost::any> items;
items.insert(make_pair("item1", shared_ptr<Interface1>(new MyClass1())));
items.insert(make_pair("item2", shared_ptr<Interface2>(new MyClass2())));
auto object = items.at("item2");
auto item = boost::any_cast<shared_ptr<Interface1>>(object);
item->DoSomething();
return 0;
}
When I run this code, nothing happens. MyClass2 doesn't appear to be calling DoSomething(), which is what I would like. How can I make the call to Interface1::DoSomething() actually call Interface2::DoSomething()? I would think it would be possible because they all inherit from each other, but I can't seem to make it work.
The reason I want this is because I have some functions which will only work with classes inherited from Interface2, but some functions need to support classes derived from either Interface1 and Interface2. Once boost::any takes over I loose which type it originally was, but it shouldn't be a problem if I could use the setup described above, so even if my original class was derived from Interface2, it could call the same function in Interface1 and get the same result.
Is there a way of doing what I want with the current setup?
EDIT:
Sorry, the void in front of the constructors where my bad, but that is not the issue.
Why do you need the boost::any?
If you need to determine the difference between Interface1 and Interface2, and you have a std::shared_pointer stored in your map, then just store a std::shared_pointer<Interface1> and use std::dynamic_pointer_cast<Interface2> to determine whether you have an Interface1 or an Interface2
Example:
#include <map>
#include <memory>
#include <iostream>
class Interface1
{
public:
virtual ~Interface1() = default;
virtual void DoSomething() = 0;
};
class Interface2 : public Interface1
{
public:
virtual ~Interface2() = default;
virtual void DoSomethingElse() = 0;
};
class MyClass1 : public Interface1
{
public:
MyClass1() {}
void DoSomething() override { std::cout << "\t\t" << __PRETTY_FUNCTION__ << '\n'; }
};
class MyClass2 : public Interface2
{
public:
MyClass2() {}
void DoSomething() override { std::cout << "\t\t" << __PRETTY_FUNCTION__ << '\n'; }
void DoSomethingElse() override { std::cout << "\t\t" << __PRETTY_FUNCTION__ << '\n'; }
};
int main()
{
std::map<std::string, std::shared_ptr<Interface1>> items;
items.emplace("item1", std::make_shared<MyClass1>());
items.emplace("item2", std::make_shared<MyClass2>());
auto check = [&items](const std::string& name)
{
auto object = items.at(name);
auto item = std::dynamic_pointer_cast<Interface2>(object);
if (item)
{
std::cout << name << " is an Interface2\n";
item->DoSomething();
item->DoSomethingElse();
}
else
{
std::cout << name << " is an Interface1\n";
object->DoSomething();
}
};
check("item1");
check("item2");
return 0;
}
Output:
item1 is an Interface1
virtual void MyClass1::DoSomething()
item2 is an Interface2
virtual void MyClass2::DoSomething()
virtual void MyClass2::DoSomethingElse()
Some final notes:
I also question the need for virtual inheritance between Interface2 and Interface1
I don't believe you need to override DoSomething in Interface2 - it's already there by publically inheriting from Interface1
virtual void DoSomething() override = 0; is unnecessary
It's not useful, but it works:
Live On Coliru
#include <map>
#include <iostream>
class Interface1
{
public:
virtual ~Interface1() {}
virtual void DoSomething() = 0;
};
class Interface2 : public virtual Interface1
{
public:
virtual ~Interface2() {}
virtual void DoSomething() override = 0;
virtual void DoSomethingElse() = 0;
};
class MyClass1 : public Interface1
{
public:
MyClass1() {}
void DoSomething() override { std::cout << __PRETTY_FUNCTION__ << "\n"; }
};
class MyClass2 : public Interface2
{
public:
MyClass2(){}
void DoSomething() override { std::cout << __PRETTY_FUNCTION__ << "\n"; }
void DoSomethingElse() override { std::cout << __PRETTY_FUNCTION__ << "\n"; }
};
#include <memory>
#include <boost/any.hpp>
int main()
{
using std::shared_ptr;
std::map<std::string, boost::any> items;
items.insert(make_pair("item1", shared_ptr<Interface1>(new MyClass1())));
items.insert(make_pair("item2", shared_ptr<Interface2>(new MyClass2())));
{
auto object = items.at("item1");
auto item = boost::any_cast<shared_ptr<Interface1>>(object);
item->DoSomething();
}
{
auto object = items.at("item2");
auto item = boost::any_cast<shared_ptr<Interface2>>(object);
item->DoSomething();
}
return 0;
}
Prints
virtual void MyClass1::DoSomething()
virtual void MyClass2::DoSomething()
Of course you need to cast to the correct interface
Found the problem. Here are the correct definitions for MyClass1 and MyClass2 :
class MyClass1 : public Interface1
{
public:
MyClass1();
void DoSomething() override;
};
class MyClass2 : public Interface2
{
public:
MyClass2();
void DoSomething() override;
void DoSomethingElse() override;
};
You have declared your constructors as void MyClass1(), which is illegal. The correct constructor syntax is MyClass1().
I don't know which compiler you're using, but I'd throw it out for not raising a syntax error.
Is it possible to have a derived class to have two sets of the same virtual functions as the base class? I'm looking to do something like the following. The idea being able to choose between two sets of function pointers.
class Base
{
virtual void func1;
virtual void func2;
};
class Derived: Base
{
float somemember;
void somefunction()
{
Base* func = this->derived_functions1;
}
class derived_functions1
{
virtual void func1()
{
return somemember*100;
}
virtual void func2;
};
class derived_functions2
{
virtual void func1;
virtual void func2;
};
};
class Base
{
public:
virtual void func1();
virtual ~Base(){}
};
struct Impl1 : Base
{
void func1() override {}
};
struct Impl2 : Base
{
void func1() override {}
};
struct Derived : Base
{
Derived(std::unique_ptr<Base> implementation) :
impl(std::move(implementation))
{}
void func1() override { impl->func1(); }
void changeImpl(std::unique_ptr<Base> implementation)
{
impl = std::move(implementation);
}
private:
std::unique_ptr<Base> impl;
};
Not the way you did. But you can make both the inner class derived_functionsX to be themseves public: Base, than have your main Derived to contain a std::unique_ptr<Base> ptryou can set to new derived_functions1 or new derived_functions2
and implement in Derived func1 and func2 to call ptr->func1() and ptr->func2().
For all that to work properly, Base must also have a virtual ~Base() {} otherwise no proper deletion can be done.
In this example, it won't compile, since derived_function1 and derived_functions2 aren't inheriting from Base.
But you could have something like this:
class Base
{
virtual void func1();
virtual void func2();
};
class Wrapper {
public:
Wrapper(int arg)
{
switch(arg)
{
case 1:
b = new derived_functions1;
break;
case 2:
b = new derived_functions2;
break;
default:
cout << "bad value of arg" << arg << endl;
exit(1);
}
}
~Wrapper()
{
delete b;
}
Base* GetClass()
{
return b;
}
private:
Base *b;
class derived_functions1: public Base
{
virtual void func1();
virtual void func2();
};
class derived_functions2: public Base
{
virtual void func1();
virtual void func2();
};
};
Short answer: No. A class can override inherited virtual functions only once.
However, there is a design pattern that exchanges function's behavior on the fly, called Strategy Pattern. In short: the class that has exchangeable behavior has a pointer to a Strategy base class that defines the interface for that behavior. It is populated with concrete Strategy classes. The function that has different behavior just delegates its calls to the Strategy pointer. Here's an example, tailored to your question:
class Base {
public:
virtual void func1() = 0;
virtual void func2() = 0;
virtual ~Base(){}
};
#include <iostream>
#include <memory>
class Derived : public Base
{
struct F1Strategy {
virtual void f1Impl() = 0;
virtual ~F1Strategy() {}
};
struct Impl1 : F1Strategy {
void f1Impl() override { std::cout << "one!\n"; }
};
struct Impl2 : F1Strategy {
void f1Impl() override { std::cout << "two?\n"; }
};
std::unique_ptr<F1Strategy> f1Strategy;
public:
Derived()
: f1Strategy(new Impl1())
{}
void func1() override { f1Strategy->f1Impl(); }
void func2() override {
static std::unique_ptr<F1Strategy> otherStrategy(new Impl2());
f1Strategy.swap(otherStrategy);
}
};
int main() {
std::unique_ptr<Base> pb(new Derived());
pb->func1(); // ==> one!
pb->func2(); //swap
pb->func1(); // ==> two?
pb->func1(); // ==> two?
pb->func2(); //swap
pb->func1(); // ==> one!
}
See it in action: http://ideone.com/zk3UTI
I need a base class that gives me primitive type of data's pointer. I add a function in it. I derived types of class. I used void * to support all primitive types as a return type but it is like old C days. It is not good for OOP. Does one have an suggestion to do in a proper way in OOP?
#include <iostream>
class base {
public:
virtual void *getPtr() = 0;
virtual ~base() {};
};
class derivedAType : public base {
protected:
int _i;
public:
derivedAType(int i): _i(0) { _i = i; };
virtual ~derivedAType() {}
virtual void *getPtr() {
return static_cast<void *>(&_i);
}
};
class derivedBType : public base {
protected:
short _s;
public:
derivedBType(short s): _s(0) { _s = s; };
virtual ~derivedBType() {}
virtual void *getPtr() {
return static_cast<void *>(&_s);
}
};
int main()
{
base *b1 = new derivedAType(1203912);
base *b2 = new derivedBType(25273);
std::cout << "b1 : " << *(static_cast<int *>(b1->getPtr()))
<< "\nb2 : " << *(static_cast<short *>(b2->getPtr()))
<< std::endl;
delete b2;
delete b1;
return 0;
}
Make the base class a template class with the data type as the template variable
template<typename DataType>
class base {
virtual DataType* getPtr() = 0;
//...
};
and
class derivedAType : public base<int>
But this changes base class to a template class which means you cant store them together, base<int> is different from base<short>
If this isnt acceptable, the other options is just a tad bit cleaner than your code but abt the same, refer to this question. Basically derived class return types can reflect their true type and i think it should get automatically converted to void*, so you dont have to manually cast the pointer.
Not sure about your problem. But maybe a double callback can help:
class Callback {
public:
virtual void do_int( int i ) const = 0;
virtual void do_short( short s ) const = 0;
/* ... */
}
class base {
public:
virtual void do_stuff(const Callback & c); /* will need a more telling name */
virtual ~base() {};
};
class derivedAType : public base {
protected:
int _i;
public:
derivedAType(int i): _i(0) { _i = i; };
virtual ~derivedAType() {}
virtual void do_stuff(const Callback & c) {
c.do_int( _i );
}
};
class derivedBType : public base {
protected:
short _s;
public:
derivedBType(short s): _s(0) { _s = s; };
virtual ~derivedBType() {}
virtual void do_stuff( const Callback & c) {
c.do_short( _s );
}
};
class print_callback : public Callback {
public:
virtual void do_int( int i ) const { std::cout << i; }
virtual void do_short( short s ) const { std::cout << s; }
}
int main() {
base *b1 = new derivedAType(1203912);
base *b2 = new derivedBType(25273);
std::cout << "b1 : ";
b1->do_stuff(print_callback());
std::cout << "\nb2 : ";
b2->do_stuff(print_callback());
std::cout << std::endl;
delete b2;
delete b1;
return 0;
}
Of course you can simplify this by just storing the created print callback, and using it twice.