How can I fix this code? The error that I'm getting is "undefined reference to 'vtable for base' "
The doSomething function should be pure if possible.
Example:
class A{
};
class A_A : public A{
};
class A_B : public A{
};
class A_C : public A{
};
/////////////////////////////////////
class base{
public:
virtual void doSomething(A* );
//virtual void doSomething(A* ) = 0; //or...
};
class derived : public base{
public:
void doSomething(A_A* );
void doSomething(A_B* );
void doSomething(A_C* );
};
By adding the =0 at the back you are forcing the derived class to override the function. This solves the issue:
class base{
public:
virtual void doSomething(A*a) = 0;
};
class derived : public base{
public:
// you can pass any derived class of A to this function
// mark as override suggested by Omid CompSCI for clarity
void doSomething(A*a) override { }
};
I hope that this helps. Also you shouldn't create 3 different versions of doSomething for each of the derived classes of A because this defeats the purpose of having all those classes inherit from A.
Also consider using smart pointers because they will handle memory dealocation for you. Check out this question. This is how I would approach this:
#include<iostream>
#include<memory>
class A
{
public:
virtual void print() = 0;
};
class A1: public A
{
public:
void print() override {std::cout << "A1" << std::endl;}
};
class A2: public A
{
public:
void print() override {std::cout << "A2" << std::endl;}
};
class A3: public A
{
public:
void print() override {std::cout << "A3" << std::endl;}
};
class base
{
public:
virtual void action(std::shared_ptr<A>) = 0;
};
class derived: public base
{
public:
// this way you can have a generic function which will handle each one of the derived classes of A.
void action(std::shared_ptr<A> a) override { a->print(); }
};
Related
I have a base class and a number of generations of descendants (derived classes):
class Base{
public:
virtual void myFunc() = 0;
}
class Derived : public Base{
//This class needs to implement myFunc()
}
class Derived2 : public Derived{
//How to force this class to implement its version of myFunc(), and force it to call Derived::myFunc as well ?
}
class Derived3 : public Derived2{
//.....should implement its own myFunc and call Derived2's mynFunc()...
}
class Derived4 : public Derived3{
//.....should implement its own myFunc and call Derived3's mynFunc()...
}
Is there a pattern to ensure:
That each derived class (regardless of whether it is an immediate descendant of the base class, or a descendant of a descendant of the base class), implement its version of myFunc?
That each derived class calls its immediate parent class myFunc?
EDIT: The pattern that comes to mind to me is Decorator pattern, but wondering if there is some better way or variation.
I propose the following solution:
#include <iostream>
template <class BaseClass>
class RequireMyFunc: public BaseClass
{
public:
virtual void myFunc() = 0; // declaration to force write implementation
protected:
void callBaseClassMyFunc() override
{
BaseClass::callBaseClassMyFunc();
BaseClass::myFunc();
}
};
class Base{
public:
void func()
{
callBaseClassMyFunc();
//myFunc();
}
virtual void myFunc(){};
protected:
Base(){}
virtual void callBaseClassMyFunc(){};
};
class Derived : public RequireMyFunc<Base>{
public:
void myFunc() override
{
std::cout << "Derived" << std::endl;
}
};
class Derived2 : public RequireMyFunc<Derived>{
public:
void myFunc() override
{
std::cout << "Derived2" << std::endl;
}
};
class Derived3 : public RequireMyFunc<Derived2>{
public:
void myFunc() override
{
std::cout << "Derived3" << std::endl;
}
};
int main()
{
Base* d = new Derived();
d->func(); // prints "Derived" (invokes only Derived::myFunc)
Base* d2 = new Derived2();
d2->func(); // prints "Derived" and "Derived2", i.e. invokes Derived::myFunc and Derived2::myFunc
Base* d3 = new Derived3();
d3->func(); // prints "Derived", "Derived2" and "Derived3"
d->myFunc(); // prints "Derived"
d2->myFunc(); // prints only "Derived2"
d3->myFunc(); // prints only "Derived3"
// Base* b = new Base(); -- cannot create because of protected constructor
//b->myFunc(); // prints nothing
}
I have two base classes and a class that inherits both base classes.
Both base classes have a virtual function with the same signature, and I want to provide different implementations in the derived class to each virtual function.
class A{
virtual void f() = 0;
}
class B{
virtual void f() = 0;
}
class Derived:public A, public B{
void A::f() override{ // Error
...
}
void B::f() override{ // Error
...
}
}
What is the correct way to do this? (I cannot rename the virtual function. Actually the two base classes are generated from the same template class.)
template <typename T>
class AShim : public A {
void f() override {
static_cast<T*>(this)->A_f();
}
};
template <typename T>
class BShim : public B {
void f() override {
static_cast<T*>(this)->B_f();
}
};
class Derived: public AShim<Derived>, public BShim<Derived> {
void A_f();
void B_f();
};
class A {
public:
virtual void f() = 0;
};
class B {
public:
virtual void f() = 0;
};
class Derived :public A, public B {
public:
void A::f() {
cout << "Inside A's version"<<endl;
}
void B::f() {
cout << "Inside B's version"<<endl;
}
};
int main()
{
Derived derived;
cout << "calling A" << endl;
A *a;
a = &derived;
a->f();
cout << "calling B" << endl;
B *b;
b = &derived;
b->f();
}
Works fine for me. No need to explicitly mention override keyword as pure virtual functions will be overridden by virtue of its default properties.Use base class's scope while defining the functions as you have already done. Use public access specifier to enable derived classes to override the pure virtual function. That's all.
I have a homework for my programming course that asks me to designs an abstract from whom derive two classes, and from those two derived classes derives another class.
This brings the Deadly Diamond of Death problem. Which can be solved by virtual inheritance, though I need instance the objects of my first two classes to a pointer of my abstract class. And this can't be done with any kind of virtual inheritance. So, if there is a way to specify the base class from which the multiple inheritance class will derive, it would be astronomically useful.
Example:
#include <iostream>
using namespace std;
class Base {
public:
virtual void foo(){};
virtual void bar(){};
};
class Der1 : public Base {
public:
virtual void foo();
};
void Der1::foo()
{
cout << "Der1::foo()" << endl;
}
class Der2 : public Base {
public:
virtual void bar();
};
void Der2::bar()
{
cout << "Der2::bar()" << endl;
}
class Join : virtual Der1, virtual Der2 {
private:
int atribb;
};
int main()
{
Base* obj = new Join();
((Der1 *)(obj))->foo();
}
Compiler error:
nueve.cpp: In function ‘int main()’:
nueve.cpp:43:30: error: ‘Base’ is an ambiguous base of ‘Join’
Base* obj = new Join();
Use virtual inheritance.
class Der1 : public virtual Base {
public:
virtual void foo();
};
class Der2 : public virtual Base {
public:
virtual void bar();
};
If virtual is declared while deriving from base class, as shown in below example, the most derived class object contains only one base class sub object, which helps in resolving the ambiguity in your case.
After doing some code changes, your final executable code:
Code changes in below sample:
Added vitual key word, while deriving the child classes.
Removed "virtual" keyword while deriving most derived class.
Modified main to invoke the member function properly.
#include <iostream>
using namespace std;
class Base {
public:
virtual void foo(){};
virtual void bar(){};
};
class Der1 : public virtual Base {
public:
virtual void foo();
};
void Der1::foo()
{
cout << "Der1::foo()" << endl;
}
class Der2 : public virtual Base {
public:
virtual void bar();
};
void Der2::bar()
{
cout << "Der2::bar()" << endl;
}
class Join : public Der1, public Der2 {
private:
int atribb;
};
int main()
{
Base* obj = new Join();
obj->foo();
}
It's not clear what you're asking for, although you seem to be saying that virtual inheritance from Base is not suitable. So, assuming that's correct, you can replace Base* obj = new Join(); with Base* obj = (Der1*)new Join(); and you'll get a pointer to the Base object that's the base of Der1. Similarly, you can replace it with Base* obj = (Der2*)new Join(); and you'll get a pointer to the Base object thats the base of Der2.
it's pretty diffecult for me to describe my problem.
I have two classes, I would say Base_A and Derived_A. You can see from the names, the class Derived_A is derived from Base_A. Also in my program I have other two classes Base_B and Derived_B (also with inheritance). The class Base_A contains the object of Base_B, and the class Derived_A contains the object of Derived_B.
class Base_A {
public:
Base_A() {}
virtual ~Base_A() {}
Base_B b_;
Base_B* pointer_;
void init() {
b_ = Base_B();
pointer_ = &b_;
pointer_->setValue(1);
}
void print() {
pointer_->getValue();
}
};
class Derived_A: public Base_A {
public:
Derived_A() {}
virtual ~Derived_A() {}
Derived_B b_;
Derived_B* pointer_;
void init() {
b_ = Derived_B();
pointer_ = &b_;
pointer_->setValue(2);
pointer_->increaseValue();
}
};
class Base_B {
public:
Base_B() {}
virtual ~Base_B() {}
int value_;
void setValue(int value) {
value_ = value;
}
void getValue() {
cout << "Base_B: " << value_ << endl;
}
};
class Derived_B: public Base_B {
public:
Derived_B() {}
virtual ~Derived_B() {}
void increaseValue() {
value_++;
}
};
int main() {
Derived_A derived_A = Derived_A();
derived_A.init();
derived_A.print();
return 0;
}
How you can see every class of A has one object of class B and pointer to this object. My problem is, when I call the function print(), it does not take Derived_B* pointer_, but try to access Base_B* pointer_, which is not exist. How I can say in my program, that it should take the pointer according to the class? Or do I need to declarate the Base_B* pointer_ inside the Derived_A class like:
Base::pointer_ = pointer_;
Maybe is there other method or algorithm for my problem?
Thank you a lot.
"but try to access Base_B* pointer_, which is not exist"
If DerivedA does not properly initialise BaseA, then DerivedA does not meet the "isA" rule for inheritance and the design needs changed. On the face of things:
Don't re-use names in the derived class such as b_, pointer_.
Its just confusing and you gain no value.
Make init() virtual.
Have DerivedA::init() call BaseA::init() explicitly.
Make pointer_ a virtual method.
Note the use of "covariant return types" for the virtual methods.
class BaseA
{
public:
virtual BaseB* pointer() { return &b_; }
// etc.
};
class DerivedA : public BaseA
{
public:
virtual DerivedB* pointer() { return &b_; }
// etc.
};
wouldn't Base_A have a pointer to Base_B if Base_A::init() was ever called?
why wouldn't you init the base class?
Is it possible to access a base class function which has the same signature as that of a derived class function using a derived class object?. here's a sample of what I'm stating below..
class base1 {
public:
void test()
{cout<<"base1"<<endl;};
};
class der1 : public base1 {
public:
void test()
{cout<<"der1"<<endl;};
};
int main() {
der1 obj;
obj.test(); // How can I access the base class 'test()' here??
return 0;
}
You need to fully qualify the method name as it conflicts with the inherited one.
Use obj.base1::test()
You can't override a method in derived class if you didn't provide a virtual key word.
class base1
{
public:
void test()
{
cout << "base1" << endl;
};
};
class der1 : public base1
{
public:
void test()
{
cout << "der1" << endl;
};
};
int main()
{
der1 obj;
obj.test(); // How can I access the base class 'test()' here??
return 0;
}
So the above code is wrong. You have to give:
virtual void test();
in your base class
You can use this:
((base)obj).test();