I am using native C++ with VSTS 2008. A quick question about virtual function. In my sample below, any differences if I declare Foo as "virtual void Foo()" or "void Foo()" in class Derived? Any impact to any future classes which will derive from class Derived?
class Base
{
public:
Base()
{
}
virtual void Foo()
{
cout << "In base" << endl;
}
};
class Derived : public Base
{
public:
Derived()
{
}
void Foo()
{
cout << "In derived " << endl;
}
};
No difference. But for the sake of readbility I always keep the virtual whenever it is.
No, as long as it has the same signature as the member function in the base class, it will automatically be made virtual. You should make it explicitly virtual, however, to avoid confusing anyone reading the code.
Related
Here is a snippet of my c++ code
class A {
public:
virtual void method() {
cout << "A::method" << endl;
}
virtual ~A() {
cout << "A::destructor" << endl;
}
};
class B : public A {
public:
virtual void method() {
cout << "B::method" << endl;
}
virtual ~B() {
cout << "B::destructor" << endl;
method();
}
};
int _tmain()
{
A* a = new B();
a->method();
delete a;
return 0;
}
I've learned that it's not preferable to call any virtual functions from constructors or destructors.
In the destructor of the derived class B, I call the virtual function named, "method()".
Here is the output message.
B::method
B::destructor
B::method
A::destructor
It seems to me there is no problem at all. The virtual function knows its object type and printed
"B::method()". Is this a kind of undefined behavior that should be avoided?
Conceptually all the virtual functions in B are accessible in the destructor body, so your code is fine and well-defined as it is.
But your code is extremely brittle: it would be a different matter if there was a child class of B which had method overridden. In that case writing B::method(); in the destructor body of B would be sufficient.
Short answer: calling virtual methods in constructors and destructors is best avoided.
I am exploring diamond problem. I have written below code. However it shows ambiguous issue. How to resolve it?
Is it possible without overriding method in Snake class?
#include <iostream>
class LivingThing {
protected:
void breathe()
{
std::cout << "I'm breathing as a living thing." << std::endl;
}
};
class Animal : virtual protected LivingThing {
protected:
void breathe() {
std::cout << "I'm breathing as a Animal." << std::endl;
}
};
class Reptile : virtual public LivingThing {
public:
void breathe() {
std::cout << "I'm breathing as a Reptile." << std::endl;
}
};
class Snake : public Animal, public Reptile {
};
int main() {
Snake snake;
snake.breathe();
getchar();
return 0;
}
What happens here is that Animal and Reptile both overwrite the LivingThing::breathe() method with their own version. Snake, thus, inherits two different methods, both called breathe, one from each of its base classes. When you then write
snake.breathe();
the name breathe is ambiguous because it could refer to either Animal::breathe or Reptile::breathe. You have to explicitly tell which one should be called, for example
snake.Reptile::breathe();
This is most likely not what you wanted. breathe() is not a virtual method. You most likely wanted it to be a virtual method, however, in which case you most definitely should have a look at How does virtual inheritance solve the "diamond" (multiple inheritance) ambiguity?.
I'm a newbie in C++ and have a question. I can't find any related stuff for this question on Google.
Is it possible in C++ for code in a virtual function to be called from the base class without invoking it with Base::func() in the derived class?
Here is an example of what I mean:
class Base {
public:
virtual void func(void) { cout << "Base func()" << endl; }
};
class Derived : Base {
public:
virtual void func(void) { cout << "Derived func()" << endl; }
};
The output should be the following when the function func is called from Derived:
Base func()
Derived func()
Is this even possible in C++? Or, is there another way to implement this behavior?
Is that intention even possible in C++? Or is there a other way to implement this behavior in C++?
You can get that behavior only if you add
Base::func();
in the implementation of Derived::func(). The language does not provide a mechanism to make that automatic.
You can make the base class get the calls first by making the interface non-virtual, and then call the (private) derived function from there:
class Base {
public:
void func()
{
cout << "Base func()" << endl;
derived_func();
}
private:
virtual void derived_func() { }
};
class Derived : Base {
private:
virtual void derived_func() { cout << "Derived func()" << endl; }
};
You have call the base class in derived class implementation to make that happen
class Base {
public:
virtual void func(void) { cout << "Base func()" << endl; }
};
class Derived : Base {
public:
virtual void func(void)
{
Base::function();
cout << "Derived func()" << endl;
}
};
But this is still calling Base::func() from Derived::func()
You can, however, achieve what you want if the func() was actually your constructor.
I'm attempting to call a method from a base class with the same name as a method in the derived class. Here's a simplified example:
#include <iostream>
using namespace std;
class Base
{
public:
void print() {
cout << "Printing from base" << endl;
}
void print(int num) {
cout << "Printing number from base: " << num << endl;
}
};
class Derived : public Base
{
using Base::print;
public:
void print() {
cout << "Printing from derived" << endl;
}
};
int main()
{
Derived x;
x.print();
x.Base::print(1);
//x.print(1); // Gives a compilation error
return 0;
}
Basically, I'd like to be able to call x.print(1) and get "Printing number from base: 1", that is, automatically call the method which matches the signature, even though it resides in the base class.
Without the using Base::print;, I get error: no matching function for call to 'Derived::print(int)', which makes perfect sense due to name hiding.
Thus, I added that line, but now the error is error: 'void Base::print(int)' is inaccessible
Why is this the case? I use public inheritance, so I would have thought it was readily available?
As demonstrated in the example, it works fine to manually call x.Base::print(1);, but I would like to do it more transparently. Then of course I can re-implement a wrapper to the function in the derived class, but that does not seem very elegant either.
I apologize if this has been covered in an earlier question, I read a bunch of them and found a lot of similar cases, but nothing that helped me.
The placement of the using directive decides about the visibility. Simply place it into the public area and you should be fine:
//...
class Derived : public Base
{
public:
using Base::print;
void print() {
cout << "Printing from base" << endl;
}
};
//...
http://ideone.com/06NNk
You can make your functions virtual. Any virtual functions inherited from the base class that aren't overloaded will be called through the derived class.
class base
{
public:
virtual void Foo() {}
}
class Derived
{
}
Derived d;
d.foo(); // calls base::foo()
Hey, so if I have a Base class and 2 derived classes...
class Base
{
virtual void Output()
{
cout << "OUTPUTTING A BASE OBJECT" << endl;
}
};
class Derived : public Base
{
void Ouput()
{
cout << "OUTPUTTING A DERIVED" << endl;
}
};
class OtherDerived : public Base
{
};
As I understand it, if I try to call Output from OtherDerived, it would fail. Is there a way to override Output for some derived versions of Base but not others?
Calling Output for objects of the OtherDerived class fails not because it's virtual, but because it's declared private in Base (well not explicitly - but private is the default in classes when nothing else is specified)
Change the declaration of Base to:
class Base
{
public:
virtual void Output()
{
cout << "OUTPUTTING A BASE OBJECT" << endl;
}
};
And this will work. protected will also work. Since Output isn't pure virtual, it can be called from subclasses that don't override it.
It would not fail - it would call Base::Output. What you want, ie. overriding "for some derived classes, but not others" is how inheritance works. You don't need to do anything further.