Suppose we want to implement strategy pattern. We have an interface Base and two derived classes -- A and B. Instances of Doer class can choose between A's and B's methods do(). And the question is how to complete the code to make how it should be.
class Base {
virtual void do() const = 0;
};
class A: public Base {
void do() const override {};
};
class B: public Base {
void do() const override {};
}
class Doer {
public:
Doer(std::unique_ptr<Base> b_ptr) : ptr(b_ptr) {}
void do() const { ptr->do(); }
private:
std::unique_ptr<Base> ptr;
}
int main() {
Doer doer(std::unique_ptr<Base>());
doer.do();
return 0;
}
Doer doer(std::make_unique<A>()); // or std::make_unique<B>()
The above is pretty much it. std::unique_ptr works very hard to implement the same coercion as the raw pointer it holds.
There are three major problems with your code.
1) do is a keyword of the language. You cannot use it as an identifier (like function name)
2) you take b_ptr by value, so you need to move from it:
Doer(std::unique_ptr<Base> b_ptr) : ptr(std::move(b_ptr)) {}
3) you pass an empty unique_ptr to Doer's constructor, which is equivalent to passing a nullptr. You also try to instantiate the base class. It is impossible because Base is a pure virtual class. Use make_unique with a derived type:
Doer doer(std::make_unique<A>());
Related
Consider the following code:
class Base {
virtual bool someFunc() = 0;
virtual ~Base() = default;
};
class Derived1 : public Base {
bool someFunc() override { ... }
};
class Derived2 : public Base {
bool someFunc() override { ... }
};
class MyClass {
public:
MyClass(std::vector<Base> derivedClasses) {
for (const auto dClass : derivedClasses) {
m_derivedClasses.emplace_back(std::make_shared<???>(dClass));
}
}
std::vector<std::shared_ptr<Base>> m_derivedClasses;
};
int main() {
std::vector<Base> listOfDerivedClasses = {Derived1(), Derived2()};
MyClass mClass(listOfDerivedClasses)
for (const auto dClass : m_derivedClasses) {
dClass.someFunc();
}
}
Essentially, I have a class that is given a list of derived classes in its constructor, and I want to convert it to a list of pointers to those derived classes so that I can execute the appropriate someFunc() function in main(). I can't seem to figure out how to get this working, do I need some template magic?
EDIT:
I could make the MyClass constructor take a std::vector<Base*> and likely get things to work like that, but it requires the consumer to create the pointers themselves and I'm hoping to shield them from that. In another class I worked on, where I wanted polymorphic behavior, I was able to achieve something like this using templates:
template <typename derivedTypeT, std::enable_if_t<std::is_base_of_v<Base, derivedTypeT>, bool> = true>
MyOtherClass(const derivedTypeT &dClass) : m_dClass(std::make_shared<derivedTypeT>(dClass)) {}
I don't know how I can make this work if the input is a std::vector though, since it obviously could have multiple derived types. Is this something I could do with variadic templates?
Is there any point to making virtual member functions, overridden from a base class private, if those are public in the base class?
struct base {
virtual void a();
};
struct derived : base {
// ...
private:
void a() override;
};
If you are forced to do a 2-phase construction on the implementation class (i.e. have an init() method as well as or instead of a constructor that has to be called (I know, but there are reasons), then this stops you calling any /other/ methods directly on the instance pointer before you pass it back as an interface pointer. Go the extra mile, make the inheritance private, and have your one public init function return the interface pointer!
Another reason is you just don't /need/ to write public: in a final implementation class declaration, so then by default everything is private. But why you would do that and use struct instead of class I don't know. Perhaps this was converted from class at some point due to a style war?
Looking at your design, I see one cannot call derived::a directly, but only through a base interface.
Is there any point? Consider that, once we have a derived instance, we can always up-cast to its base, so given
derived d;
while d.a() wouldn't compile, we can always do
base & b = d;
b.a(); //which actually calls derived::a
In other words: derived::a is not that private, after all, and I would discourage this design, which can be confusing to the user.
Things change if the members private in derived are private in base, as well: this time it is clear that they just cannot be called directly, outside base or derived.
Let's say we have a couple of functions, and want them to be called conditionally, according to a value passed as an argument to a third one:
struct base
{
void dosomething(bool x)
{
if(x)
{
do_this();
}
else
{
do_that();
}
}
private:
virtual void do_this(){}
virtual void do_that(){}
};
Thus a derived class could be like:
struct derived : base
{
private:
void do_this() override { }
void do_that() override { }
};
and no other class can call them, unless it extended base itself:
derived d;
d.dosomething(true); //will call do_this() in derived
d.dosomething(false); //will call do_that() in derived
d.do_that() //won't compile
Yes, if you inherit the base class as private. Otherwise, it is more of a weird explicit-like restriction - user has to has to make an explicit conversion to use the function - it is generally ill advised as few will be able to comprehend the author's intention.
If you want to restrict some functions from base class, make a private/protected inheritance and via using keyword declare which base-methods you want to be protected/public in the derived class.
The same reasoning as for non-virtual methods applies: If only the class itself is supposed to call it make it private.
Consider the template method pattern:
struct base {
void foo() { a() ; b(); }
virtual void a() = 0;
virtual void b() = 0;
};
struct derived : base {
private:
void a() override {}
void b() override {}
};
int main()
{
derived().foo();
}
Perhaps a and b should have been protected, but anyhow the derived can change accesibility and it requires some documentation so that derived knows how it is supposed to implement a and b.
I have an abstract base class which declares a pure virtual function (virtual method() = 0;). Some of the inherited classes specialize and use this method but there's one of those inherited classes in which I don't want to make this method usable. How do I do it? Is making it private the only choice?
Well, you could throw that will make tacking where it is called easier.
void method() override { throw /* whatever */ ; }
Dynamic polymorphism is a runtime property. Hence a runtime error. If you look after something that will trigger at compile time, you need static polymorphism.
template<typename Child>
struct Parent {
void callMe() {
static_cast<Child*>(this)->callMeImpl();
}
};
struct SomeChild : Parent<SomeChild> {
};
Now, if you try to call callMe form the parent that is extended by SomeChild, it will be a compile time error.
You can also hold pointer to the parent just like dynamic polymorphism, as the parent will call the child function
Is making it private the only choice?
No, that's not a choice at all since you can still access the method if it's public or protected in the base classes.
Other than implementing the method in the class and resorting to run-time failures, there's not a lot you can do. You could port the whole thing to templates and use static polymorphism which, with further trickey, you could contrive a compile-time failure in certain instances, but that could be design overkill.
I guess you could make it a normal virtual function instead of a pure virtual function like this:
virtual void method() { /* code */ }
If this function is not being used in another class, you will be able to catch that. For example you could warn yourself:
virtual void method() { error = true; } //or whatever
As others have said there is no way of enforcing this at compile time. If you are referring to a pointer to a base class there is no way the compiler can know if that pointer is referring to one of the derived classes that does implement this method or one that doesn't.
So the case will have to be handled at runtime. One option is to just throw an exception. Another option is to introduce a level of indirection so that you can ask your base class if it implements a certain function before you call it.
Say you have a Base class with three methods foo, bar and doit and some derived classes do not want to implement foo then you could split up the Base class into two base classes:
class Base1 {
public:
virtual void foo() = 0;
};
class Base2 {
public:
virtual void bar() = 0;
virtual void doit() = 0;
};
Then in places where you are currently using Base you instead use a BaseSource:
class BaseSource {
public:
virtual Base1* getBase1() = 0;
virtual Base2* getBase2() = 0;
};
where getBase1 and getBase2 can return nullptr if a BaseSource does not offer that interface:
class Derived : public BaseSource, public Base2 {
public:
// don't implement foo();
// Implemementation of Base2
void bar() override;
void doit() override;
Base1* getBase1() override { return nullptr; } // Doesn't implement Base1
Base2* getBase2() override { return this; }
};
int main() {
std::vector<std::unique_ptr<BaseSource>> objects;
objects.push_back(std::make_unique<Derived>());
for (auto& o : objects) {
auto b1 = o->getBase1();
if (b1)
b1->foo();
auto b2 = o->getBase2();
if (b2)
b2->bar();
}
}
Live demo.
I've got a base class that has a virtual function. I want to call that class during the construction because I want the function called for each of the derived classes. I know I can't call a virtual function during construction, but I can't think of an elegant (i.e., avoid repeating code) solution.
What are some work arounds to calling a virtual function during construction?
The reason I want to avoid this is because I don't want to have to create constructors that just call the base class.
class A {
public:
A() {
read();
}
// This never needs to be called
virtual void read() = 0;
}
class B:A {
public:
B():A() { };
read() { /*Do something special for B here.*/ }
}
class C:A {
public:
C():A() { };
read() { /*Do something special for C here.*/ }
}
PS: The Python way of doing this is simply to raise NotImplementedError in A::read(). I'm returning to C++ and I'm more rusty than I thought.
The FAQ perspective.
This is a Frequently Asked Question.
See the C++ FAQ item titled “Okay, but is there a way to simulate that behavior as if dynamic binding worked on the this object within my base class's constructor?”.
It’s very often a good idea to check the FAQ (and generally, googling or altavista’ing) before asking.
The question as “Derived class specific base initialization”.
To be clear, while the literal question above is
“What are some work arounds to calling a virtual function during construction?”
it is evident that what’s meant is
“How can a base class B be designed so that each derived class can specify part of what goes on during B construction?”
A major example is where C style GUI functionality is wrapped by C++ classes. Then a general Widget constructor might need to instantiate an API-level widget which, depending on the most derived class, should be a button widget or a listbox widget or whatever. So the most derived class must somehow influence what goes on up in Widget’s constructor.
In other words, we’re talking about derived class specific base construction.
Marshall Cline called that “Dynamic Binding During Construction”, and it’s problematic in C++ because in C++ the dynamic type of an object during class T construction and destruction, is T. This helps with type safety, in that a virtual member function is not called on a derived class sub-object before that sub-object has been initialized, or its initialization has started. But a major cost is that DBDI (apparently) can’t be done in a way that is both simple and safe.
Where the derived class specific init can be performed.
In the question the derived class specific action is called read. Here I call it derived_action. There are 3 main possibilities for where the derived_action is invoked:
Invoked by instantiation code, called two-phase construction.
This essentially implies the possibility of having a mostly unusuable not fully initialized object at hand, a zombie object. However, with C++11 move semantics that has become more common and accepted (and anyway it can be mitigated to some extent by using factories). A main problem is that during the second phase of construction the ordinary C++ protection against virtual calls on uninitialized sub-objects, due to dynamic type changes during construction, is not present.
Invoked by Derived constructor.
For example, derived_action can be invoked as an argument expression for the Base constructor. A not totally uncommon technique is to use a class template to generate most derived classes that e.g. supply calls of derived_action.
Invoked by Base constructor.
This implies that knowledge of derived_action must be passed up to the constructor, dynamically or statically. A nice way is to use a defaulted constructor argument. This leads to the notion of a parallel class hierarchy, a hierarchy of derived class actions.
This list is in order of increasing sophistication and type safety, and also, to the best of my knowledge, reflects the historical use of the various techniques.
E.g. in Microsoft’s MFC and Borland’s ObjectWindows GUI early 1990’ libraries two-phase construction was common, and that kind of design is now, as of 2014, regarded as very ungood.
This is the factory method approach, putting the factory into the base class:
class A {
public:
virtual void read() = 0;
template<class X> static X* create() {X* r = new X;X->read();return X;}
virtual A* clone() const = 0;
};
class B : public A {
B():A() { };
friend class A;
public:
void read() { /*Do something special for B here.*/ }
B* clone() const {return new B(*this);}
};
class C : public A {
C():A() { };
friend class A;
public:
void read() { /*Do something special for C here.*/ }
C* clone() const {return new C(*this);}
};
Added a clone-method with covariant return type as a bonus.
Using CRTP:
class A {
public:
// This never needs to be called
virtual void read() = 0;
virtual A* clone() const = 0;
};
template<class D, class B> struct CRTP : B {
D* clone() {return new D(*this);}
static D* create() {return new D();}
};
class B : public CRTP<B, A> {
B() { };
public:
void read() { /*Do something special for B here.*/ }
};
class C : public CRTP<C, A> {
C() { };
public:
void read() { /*Do something special for C here.*/ }
};
One way to achieve this, would be simply to delegate it to another class (that is perhaps a friend) and can be sure to be called when fully constructed.
class A
{
friend class C;
private:
C& _c; // this is the actual class!
public:
A(C& c) : _c(c) { };
virtual ~A() { };
virtual void read() = 0;
};
class B : public A
{
public:
B(C& c) : A(c) { };
virtual ~B() { };
virtual void read() {
// actual implementation
};
};
class C
{
private:
std::unique_ptr<A> _a;
public:
C() : _a(new B(*this)) { // looks dangerous? not at this point...
_a->read(); // safe now
};
};
In this example, I just create a B, but how you do that can depend on what you want to achieve and use templates on C if necessary, e.g:
template<typename VIRTUAL>
class C
{
private:
using Ptr = std::unique_ptr<VIRTUAL>;
Ptr _ptr;
public:
C() : _ptr(new VIRTUAL(*this)) {
_ptr->read();
};
}; // eo class C
The workaround is to call the virtual function after construction. You can then couple the two operations (construction + virtual call) in factory function. Here is the basic idea:
class FactoryA
{
public:
A *MakeA() const
{
A *ptr = CreateA();
ptr->read();
return ptr;
}
virtual ~FactoryA() {}
private:
virtual A *CreateA() const = 0;
};
class FactoryB : public FactoryA
{
private:
virtual A *CreateA() const { return new B; }
};
// client code:
void f(FactoryA &factory)
{
A *ptr = factory.MakeA();
}
As mentioned by Benjamin Bannier, you can use CRTP (a template which defines the actual read() function.) One problem with that method is that templates have to always be written inline. That can at times be problematic, especially if you are to write really large functions.
Another way is to pass a function pointer to the constructor. Although, in a way, it is similar to calling the function in your constructor, it forces you to pass a pointer (although in C++ you could always pass nullptr.)
class A
{
public:
A(func_t f)
{
// if(!f) throw ...;
(*f)();
}
};
class B : A
{
public:
B() : A(read) {}
void read() { ... }
};
Obviously, you have the "can't call other virtual functions" problem within the read() function and any function it calls. Plus, variable members of B are NOT yet initialized. That is probably a much worst problem in this case...
For that reason, writing it this way is safer:
B() : A()
{
read();
}
However, in cases like that, that may be the time when you an some for of init() function. That init() function can be implemented in A() (if you make it accessible: i.e. use public A when deriving) and that function can call all the virtual functions as expected:
class A
{
public:
void init()
{
read();
}
};
class B : public A
{
public:
...
};
I know a lot of people say that an init() function is evil because people who create a B object now need to know to call it... but there isn't much else you can do. That being said, you could have a form of factory, and that factory can do the init() call as required.
class B : public A
{
public:
static B *create() { B *b(new B); b->init(); return b; }
private:
B() { ... } // prevent creation without calling create()
};
Say B and C are derived from A. I want to be able to test whether any two instances of classes derived from A are instances of the same class, that is, whether A* foo and A* bar both point to B instances, without using RTTI. My current solution is something like this:
class A {
protected:
typedef uintptr_t Code;
virtual Code code() const = 0;
}; // class A
class B : public A {
protected:
virtual Code code() const { return Code(&identity); }
private:
static int identity;
}; // class B
class C : public A {
protected:
virtual Code code() const { return Code(&identity); }
private:
static int identity;
}; // class C
Using this method, operator== can simply test first.code() == second.code(). I'd like to remove the literal identity from the derived classes and have the code found automatically by A, so that not all of the derived classes have to repeat this idiom. Again, I would strongly prefer not to use RTTI. Is there any way to do this?
Note: I have seen recent questions [1] and [2], and this is not a duplicate. Those posters want to test the contents of their derived classes; I merely want to test the identities.
You should just use RTTI instead of reinventing the wheel.
If you insist on not using RTTI, you could use CRTP and a function-local static variable to avoid having to write the function to every derived class. Adapt from this example code I wrote for Wikipedia: http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern#Polymorphic_copy_construction
Another alternative is reading the vtable pointer (via this and pointer arithmetics), but that would depend on both the compiler and the platform, so it is not portable.
Your idea is on the right track; maybe you can eliminate some boilerplate with a template:
class TypeTagged {
public:
virtual Code code() const = 0;
}
template <class T>
class TypeTaggedImpl: public virtual TypeTagged {
public:
virtual Code code() const { return Code(&id); }
private:
static int id;
}
Then your client classes just need to be declared like this:
class A: public TypeTaggedImpl<A> { ... }
class B: public A, public TypeTaggedImpl<B> { ... }
The different instantiations of TypeTagged mean that the types have different id fields and hence different IDs; the virtual base type means that the code for the most derived type gets returned.
You can have the Base class to take id as a constructor parameter and implement the identity() function in base class itself. Then there is no need to repeat the code in derived classes. In the derived class constructor, you can do something like derived::derived(): base(0) Sample Code:
class A
{
public:
A(int n) : m_id(n)
{
}
virtual ~A(){}
virtual int id() const
{
return m_id;
}
private:
int m_id;
};
class B : public A
{
public:
B() : A(0)
{
}
};
you can use the both macro __FILE__ __LINE__ as your code
this will avoid the collision problem
you can map this values to an int