class Base {
public:
virtual void myFunc(double a, double b) { };
virtual void myFunc(double a) { };
};
class Derived : public Base {
public:
virtual void myFunc(double a) { return this->myFunc(a, 0.0); };
}; // ^^^^^^^^^^^^^^^^^^^^
The previous code won't compile : error C2660: 'Derived::myFunc' : function does not take 2 arguments
Apparently the compiler cannot see that I'm trying to call the function defined in Base class, or any function that overrides it. On the other hand, the following code compiles ok:
class Base {
public:
virtual void myFunc2(double a, double b) { };
virtual void myFunc(double a) { };
};
class Derived : public Base {
public:
virtual void myFunc(double a) { return this->myFunc2(a, 0.0); };
};
I think what i'm trying to do in the first example is legal C++, so is this a bug in the VS2010 compiler? I have the same results with VS2008
thanks
edit : a workaround I found is to use
virtual void myFunc(double a) { return ((Base*)this)->myFunc(a, 0.0); };
but I'm not 100% sure it has the exact same effect, can anyone confirm?
This behavior is by design.
Functions in a derived class hide other overloads in the base class.
This is not a bug.
You have a choice in C++ whether the inherited overloads should be hidden (which is the safer, default behavior) or available:
class Derived : public Base {
public:
virtual void myFunc(double a) { return this->myFunc(a, 0.0); };
using Base::myFunc;
};
Alternatively, you can use the Base::myFunc syntax at the point of the function call.
There is an explanation of the default behavior of interaction between namespaces and overloading in D&E, section 17.4.5.3 and 17.5. Suppose that Base is a library class whereas Derived is your application code. The next version of the library will certainly have new overloads for many functions, possibly even myFunc, and you certainly do not want your well tested program to silent rebind its myFunc calls to other overloads and call something else.
Related
I have several classes D with public sections of the form:
class D
{
public:
D& foo();
void bar(D&);
}
I'd like to create a single abstract class from which they all derive.
My (naive) attempt was:
// in .h file
class B
{
public:
virtual B& foo() = 0;
virtual void bar(B&) = 0;
}
class D : public B
{
public:
D& foo() override;
void bar(D&) override;
}
// in .cpp file
D& D::bar() {return *(new D());}
void D::foo(D& d) {}
This failed to compile for (what I eventually realized was) a fairly sensible reason: Any function overriding the function
void bar(B&)=0;
must be defined for any parameter which is a reference to type B. The supplied candidate
virtual void bar(D&) override;
is only defined for (the smaller collection) of parameters which are references to type D.
Note that this is not a problem with the function foo. Indeed, if you comment out the three lines with bar, everything compiles fine.
I think that the technical explanation for this phenomenon is that C++ does not support covariance in parameters (but it does support contravariance in parameters).
The answer to the post C++ covariance in parameters suggests that I can't define an interface (i.e. an abstract class) for my classes D.
Is there some simple or conventional way to create a single "interface" for all my classes D? Alternatively, perhaps there is a different design pattern for hiding the different implementations of these classes.
Thanks in advance for your comments and suggestions.
dan
You can't, and for good reason. A derived class can't add preconditions that are more restrictive than the interface it derives from without breaking every principle of OOP that exists. By requiring the parameter to be more specific in your implementation of the interface this is exactly what you are doing.
An argument could be made that something like this could be useful:
struct IfaceA {};
struct IfaceB : IfaceA {};
struct Base { void f(IfaceB &); };
struct Derived : Base { void f(IfaceA &); };
This lessens preconditions rather than increase them, so it's OK. It's simply not done in C++, or any other language I'm aware of for that matter, so you just can't do it.
In both cases you can make an overload with the alternative parameter type and call the overridden version.
It's the opposite case with return types. Return values are post-conditions. You can make post conditions more specific, but can't make them more broad. So you can return your derived type but can't broaden it by returning a more abstract type. C++ implements covariant returns though at least one, very commonly used compiler does it very badly so that there are numerous bugs.
Based on the code that you have provided you have tried to override two diferent function signatures.
The best option you have is use the same signature, and then cast the result.
A simple example,
// in .h file
class B
{
public:
virtual B* foo() = 0;
virtual void bar(B*) = 0;
};
class D : public B
{
public:
B* foo() override;
void bar(B*) override;
};
// in .cpp file
B* D::foo()
{
D* p=new D();
return p;
}
void D::bar(B* d)
{
D* casted=dynamic_cast<D*>(d);
}
int main(void)
{
D son;
B* father=dynamic_cast<B*>(son.foo());
}
I hope that this can solve your problem, or at least give you a clue.
Could you use a templated base class?
template <typename Deriving>
struct Base {
virtual Deriving& foo() = 0;
virtual void bar(Deriving&) = 0;
};
struct Deriving : public Base<Deriving> {
...
};
You don't have a single interface class, but there is a single interface template, which is sometimes versatile enough.
Summary
I relied on the compiler to point to every location in my code I would need to update while changing the signature of a member function in a parent class, but the compiler failed to point out an overridden instance of that function in a child class, causing a logical error in my program. I would like to re-implement the classes so that I can rely more on the compiler while making changes of this kind.
Details via an example
I have the following classes:
class A
{
public:
void foo();
virtual void bar();
}
class B: public A
{
public:
void bar();
}
This is the implementation:
void A:foo(){ ... bar(); ... }
void A:bar(){ ... }
void B:bar(){ ... }
Note that whhen I call b->foo() (where b has type B* and B is a subclass of A) the bar() method called is B:bar()
After changing the type-signature of A:bar(), to say A:bar(some_parameter), my code looked like this:
void A:foo(){ ... bar(param); ... }
void A:bar(param) { ... }
void B:bar(){ ... }
Now, when I call b->foo(), of course A:bar(param) is called. I expected such a case to be caught by the compiler, but I realize now that it cannot.
How would I implement classes A & B to avoid bugs of this class.
I expected such a case to be caught by the compiler, but I realize now
that it cannot do so.
Actually, it can do so. You can use override on B::bar's declaration, and the compiler will error if there is no suitable base class function for it to override.
The way to detect this issue in c++03 where it did not have yet the override specifier (It is since c++11 standard) is to do pure virtual method in an interface. If you change the sign of a pure virtual method, all its subclasses must change it too or they will not compile.
Do not depend on concrete classes. Depend on interfaces. You will do better designs.
Your design would change to something like this:
class IA
{
public:
void foo() { ... bar(); ...}
virtual void bar() = 0;
virtual ~IA() {}
};
class A : public IA
{
public:
void bar() {...}
};
class B : public IA
{
public:
void bar() {...}
};
Now, if you change the sign of bar in the interface, all its subclasses must change it too.
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()
};
I have the following structure
class Base
{
public:
Base(Type);
virtual render
}
class A
{
public:
Base(Type == A);
void render()
}
class B
{
public:
Base(Type == B);
void render()
}
void client_function()
{
Base baseObject(A);
//Base is an instance of class A
baseObject.render()//runs class A render
}
There are things in the above code that are not c++ as far as I am aware, they are closely related to pattern matching found in Haskell for example, but this is the best way I could find to illustrate my question without already knowing the answer ;)
In writing I want the client to be able to create a base object and pass the type of object as an argument, the correct specification of the object is returned and the client need not care less about it, just knows that running render will run the correct specific render.
Please feel free to ask questions if I have been unclear :)
I think you need to read about virtual functions and inheritance:
http://www.parashift.com/c++-faq-lite/virtual-functions.html
http://www.parashift.com/c++-faq-lite/proper-inheritance.html
http://www.parashift.com/c++-faq-lite/abcs.html
You need run-time polymorphism. There is not much important part of constructor. You have to inherit the Base into A and B. For example:
class Base
{
public:
virtual void render (); // <--- declare 'virtual'
virtual ~Base(); // <--- very much needed to avoid undefined behavior
};
class A : public Base //<---- inheritance
{
public:
void render(); // <--- this also becomes 'virtual'
};
...
Now you can use as per your requirement.
Base *baseObject = new A(); // <----- need to use pointer (or reference)
(*baseObject).render(); // <--- other way to write: baseObject->render();
delete baseObject;
I'm not sure I understood your question. In C++ you cannot choose your base class at runtime, but you certainly can have your base class depend from the derived class. This is done by using templates and what is known as the Curiously Recurring Template Pattern:
template <typename T> class Base {
public:
virtual void render(T *) {}
};
class A : public Base<A>
{
public:
void render(A * t) {}
};
class B : public Base<B>
{
public:
void render(B * t) {}
};
void client_function() {
A a1;
A a2;
a1.render(&a2); // calls A::render
a1.Base<A>::render(&a2); // calls Base<A>::render
Base<A> * ba = &a1;
ba->render(&a2); // calls A::render
}
Hope this answers your question.
What you ask for is exactly what inheritance is for: creating object from a class hierarchy that specializes a functionality.
In your example, apart from syntax problems, things will work as you expect, i.e. method A::render will be called, even if you don't know at compile time that object, declared as a Base, is indeed a A. That's virtual inheritance magicness.
If I have a code like this:
struct A {
virtual void f(int) {}
virtual void f(void*) {}
};
struct B : public A {
void f(int) {}
};
struct C : public B {
void f(void*) {}
};
int main() {
C c;
c.f(1);
return 0;
}
I get an error that says that I am trying to do an invalid conversion from int to void*. Why can't compiler figure out that he has to call B::f, since both functions are declared as virtual?
After reading jalf's answer I went and reduced it even further. This one does not work as well. Not very intuitive.
struct A {
virtual void f(int) {}
};
struct B : public A {
void f(void*) {}
};
int main() {
B b;
b.f(1);
return 0;
}
The short answer is "because that's how overload resolution works in C++".
The compiler searches for functions F inside the C class, and if it finds any, it stops the search, and tries to pick a candidate among those. It only looks inside base classes if no matching functions were found in the derived class.
However, you can explicitly introduce the base class functions into the derived class' namespace:
struct C : public B {
void f(void*) {}
using B::f; // Add B's f function to C's namespace, allowing it to participate in overload resolution
};
Or you could do this:
void main()
{
A *a = new C();
a->f(1); //This will call f(int) from B(Polymorphism)
}
Well I think first of all you did not understand what virtual mechanism or polymorhism. When the polymorphism is achieved only by using object pointers. I think you are new to c++. Without using object pointers then there is no meaning of polymorphism or virtual keyword use base class pointer and assign the desired derived class objects to it. Then call and try it.