class Base {
public:
Base(){ }
virtual void Bfun1();
virtual void Bfun2();
};
class Derv : public Base {
public:
Derv(){ }
void Dfun1();
};
Is there a difference between above definitions and the below ones ? Are they same ? if not how both are the different functionally ?
class Base {
public:
Base(){ }
void Bfun1();
void Bfun2();
};
class Derv : public virtual Base {
public:
Derv(){ }
void Dfun1();
};
They are completely different. The first set defines Bfun1 and Bfun2 as virtual function, that allows overriding them in the derived class and call those in the derived class through a base class pointer:
// assume you've overridden the functions in Derived
Base* base_ptr = new Derived;
base_ptr->Bfun1(); // will call function in derived
The second set, however, they're just normal functions. Instead, you declared the base class to be virtual, which has many implications you best read about in a good C++ book or search through the SO questions, I think we have one on that topic.
Related
Lets say we have following hierarchy:
class Abstract
{
public:
virtual void foo() = 0;
};
class Base : public Abstract
{
public:
virtual void foo() override; //provides base implementation
};
class Derived : public Base
{
public:
virtual void foo() override; //provides derived implementation
};
If Base::foo() is ever called on the Derived object that object will desync and its data will be corrupted. It inherits Base's data structure and its manipulation but needs to perform additional operations so calling only the Base::foo() will omit these extra operations and as a result the Derived's state will be corrupted.
Therefore I would like to prevent direct call of Base implementation of foo so this:
Derived d;
d.Base::foo();
ideally, should give me a compile time error of some sorts. Or do nothing or otherwise be prevented.
However it might be I am violating the polymorphism rules and should use composition instead but that would require a lots of extra typing...
How about template method pattern:
class Abstract
{
public:
void foo() { foo_impl(); }
private:
virtual void foo_impl() = 0;
};
class Base : public Abstract
{
private:
virtual void foo_impl() override; //provides base implementation
};
class Derived : public Base
{
private:
virtual void foo_impl() override; //provides derived implementation
};
then
void test(Abstract& obj) {
obj.foo(); // the correct foo_impl() will be invoked
}
Derived d;
test(d); // impossible to call the foo_impl() of Base
You can explore the template method pattern. It allows for greater control of the execution of the methods involved.
class Abstract
{
public:
virtual void foo() = 0;
};
class Base : public Abstract
{
protected:
virtual void foo_impl() = 0;
public:
//provides base implementation and calls foo_impl()
virtual void foo() final override { /*...*/ foo_impl(); }
};
class Derived : public Base
{
protected:
virtual void foo_impl() override; //provides derived implementation
};
The pattern is seen in the iostreams library with sync() and pubsync() methods.
To prevent the direct calls and maintain the consistent state, you will need to get the final implementation of the foo method in the correct place in the stack. If the intent is to prohibit the direct call from the top of the hierarchy, then you can move the _impl methods up.
See also the non-virtual interface, the NVI pattern.
Bear in mind as well that the overriding methods do not have to have the same access specifier as the Abstract class. You could also just make the methods in the derived classes private or protected;
class Abstract
{
public:
virtual void foo() = 0;
};
class Base : public Abstract
{
virtual void foo() override; //provides base implementation
};
class Derived : public Base
{
virtual void foo() override; //provides derived implementation
};
Note: unless otherwise intended, changing the access specifier could be considered bad design - so basically if you do change the access specifier, there should should be a good reason to do so.
You can make all the foo() methods non-public, then have a non-virtual function in the Abstract class that simply calls foo.
Lets suppose you want to make an interface of the class Derived and it looks like this:
class Derived : public Base
{
public:
foo();
}
class Base
{
public:
tii();
//many other methods
}
How would you do the Interface? How can you make Base::tii visible (and also other methods) to this new interface?
class IDerived
{
public:
virtual foo() = 0;
// should I declare here tii() as a pure virtual function?
// but by doing it now there is ambiguity!
}
What is a good strategy?
The new Derived class should look like this....
class Derived : public Base, public IDerived
{
//implement the real thing
}
Your example is doing things backwards: the interface should be defined independently of any concrete classes with all pure virtual methods:
class IDerived
{
public:
virtual void foo() = 0;
virtual ~IDerived() {} // don't forget to include a virtual destructor
}
And the concrete classes will derive publicly from the interface:
class Derived : public Base, public IDerived
{
public:
void foo();
}
If you want IDerived to also declare methods that Derived inherits from Base, you can have Derived explicitly implement the method by calling the inherited implementation:
class Derived : public Base, public IDerived
{
public:
void foo();
void bar() { Base::bar(); }
}
At front, I dislike interfaces (they are grown by other languages than c++).
Anyway, if you have one, it should be complete: Hence have the 'tii() as a pure virtual function'. To resolve the conflict rewrite that function in 'Derived' (forward to Base::tii).
Must virtual methods be always implemented in derived class?
Can I write something like this?
<!-- language: lang-cpp -->
class BaseInterface
{
public:
virtual void fun_a() = 0;
virtual void fun_b() = 0;
virtual ~BaseInterface();
};
class Derived : public BaseInterface
{
void fun_a() { ... };
};
class FinalClass : public Derived
{
void fun_b() { ... };
}
int main()
{
FinalClass test_obj;
test_obj.fun_a(); // use Derived implementation or fail ???
test_obj.fun_b(); // use own implementation
BaseInterface* test_interface = new FinalClass();
test_interface->fun_a(); // fail or ok ???
test_interface->fun_b();
}
Is the code above correct?
Does another virtual method outflank exist?
Pure virtual methods always must be reimplemented in derived class?
Actually a derived class which is going to be instantiated.
In your code, you didn't make an object from Derived so it's OK.
Can i write something like this?
Yes.
You had some minor errors that I corrected them:
class BaseInterface
{
public:
virtual void fun_a() = 0;
virtual void fun_b() = 0;
virtual ~BaseInterface() {}; // You forget this
};
class Derived : public BaseInterface
{
public:
void fun_a() {} // This should be public as its base
};
class FinalClass : public Derived
{
public:
void fun_b() {} // This should be public as its base
};
int main()
{
FinalClass test_obj;
test_obj.fun_a();
test_obj.fun_b();
BaseInterface* test_interface = new FinalClass();
test_interface->fun_a();
test_interface->fun_b();
}
It makes Derived also an abstract class which you cannot instantiate, seeing you don't implement all the virtual functions from it's base, it becomes an abstract class you cannot directly instantiate.
See here: liveworkspace.org/code/6huYU$10
For the rest, your code should work.
Code is correct.
There is no special concept for interface in C++. All are classes. Some of the class methods can be pure virtual. It only means that compiler cannot create an instance of such class.
I have 6 classes which all perform the same actions. I would like to move common behavior to a common [base] class.
There are actions to be performed on 6 separate objects. The six objects are located in derived classes. Intuitively, the private member objects would be accessed through the child (derived class) in the base class.
What is the C++ pattern I am looking for?
class Base
{
// Common behavior, operate on m_object
...
void Foo()
{
m_object.Bar();
}
};
class Derived1 : public Base
{
// No methods, use Base methods
private:
MyObject1 m_object;
}
class Derived2 : public Base
{
// No methods, use Base methods
private:
MyObject2 m_object;
}
The thing that is boxing me into this situation is MyObject1, MyObject2, etc offer Bar(), but don't share a common base class. I really can't fix the derivation because the objects come from an external library.
If they are introduced in the derived classes, then the base class cannot directly access them. How would the base class know that all derived classes have a specific member?
You could use virtual protected methods like so:
class my_base
{
protected:
virtual int get_whatever();
virtual double get_whatever2();
private:
void process()
{
int y = get_whatever();
double x = get_whatever2();
//yay, profit?
}
}
class my_derived_1 : my_base
{
protected:
virtual int get_whatever()
{
return _my_integer;
}
virtual double get_whatever2()
{
return _my_double;
}
}
Another possibility (if you want to call the base methods from the derived classes) is to simply supply the arguments to the base methods.
class my_base
{
protected:
void handle_whatever(int & arg);
};
class my_derived : my_base
{
void do()
{
my_base::handle_whatever(member);
}
int member;
};
C++ does and doesn't. It has a very powerful multiple inheritance support, so there is no super keyword. Why? Imagine that your base class is, say, inherited by another two classes, or even is a part of virtual inheritance hierarchy. In that case you can't really tell what super is supposed to mean. On the other hand, there are virtual methods, you can always have them in base class and implement in derived classes (that's what languages like Java do, except that they they don't have multiple class inheritance support). If you don't want to go with polymorphism, you can use something like this:
#include <cstdio>
template <typename T>
struct Base
{
void foo ()
{
std::printf ("Base::foo\n");
static_cast<T *> (this)->bar ();
}
};
struct Derived : Base<Derived>
{
void bar ()
{
std::printf ("Derived::bar\n");
}
};
int
main ()
{
Derived d;
d.foo ();
}
This is an extremely simple example - you can extend the above example with access control, friends, compile-time assertions etcetera, but you get the idea.
Have you considered not using inheritance?
class FooBar
{
MyObject m_object;
public:
FooBar(MyObject m): m_object(m) {}
//operate on different m_objects all you want
};
What about deriving your six separate objects from a common base class? Then you can declare virtual methods in that base class to create your interface, and then implement them in the derived object classes.
Maybe you just need a template instead of superclass and 6 derived classes?
It seems that you need to access not the parent's, but child's field. You should do it by introducing an abstract method:
class ParentClass
{
public:
void f();
protected:
virtual int getSomething() = 0;
};
ParentClass::f()
{
cout << getSomething() << endl;
}
class DerivedClass : public ParentClass
{
protected:
virtual int getSomething();
}
DerivedClass::getSomething() { return 42; }
If you need to access parent's method, just use ParentClass::method(...):
class ParentClass
{
public:
virtual void f();
};
class DerivedClass : public ParentClass
{
public:
virtual void f();
};
void DerivedClass::f()
{
ParentClass::f();
}
In C++, let's say I have a class Derived that implements an interface class BaseInterface, where BaseInterface has only pure virtual functions and a virtual destructor:
class BaseInterface
{
public:
virtual void doSomething() = 0;
~BaseInterface(){}
};
class Derived : public BaseInterface
{
public:
Derived() {}
~Derived(){}
protected:
virtual void doSomething();
private:
int x;
};
No classes outside the Derived class hierarchy should call Derived::doSomething() directly, i.e., it should only be accessed polymorphically through the BaseInterface class. To enforce this rule, I have made Derived::doSomething() protected. This works well, but I'm looking for opinions pro/con regarding this approach.
Thanks!
Ken
I think you're looking for the non-virtual interface (NVI) pattern: a public non-virtual interface that calls a protected or private virtual implementation:
class BaseInterface
{
public:
virtual ~BaseInterface(){}
void doSomething() { doSomethingImpl(); }
protected:
virtual void doSomethingImpl() = 0;
};
class Derived : public BaseInterface
{
public:
Derived() {}
virtual ~Derived(){}
protected:
virtual void doSomethingImpl();
private:
int x;
};
If it is part of the interface, why would you not want users to call it? Note that as it is, they can call it: static_cast<BaseInterface&>(o).doSomething() is just an awkward way of saying o.doSomething(). What is the point of using the interface... if the object fulfills the interface, then you should be able to use it, or am I missing something?
Since you are not actually blocking anyone from calling the methods, I don't see a point in making the code more complex (both the class and users of the class) for no particular reason. Note that this is completely different from the Non-Virtual Interface in that in this idiom virtual functions are not accessible publicly (at any level) while in your case, the intention is allowing access, and making it cumbersome.
What you are doing is also mentioned in standard ISO/IEC 14882:2003(E) 11.6.1 and believe you are correct. Other than the fact, the member function isn't pure virtual in the given example. It should hold for pure virtual functions too, AFAIK.
The access rules (clause 11) for a virtual function are determined by its declaration and are not affected by the rules for a function that later overrides it.
[Example:
class B
{
public:
virtual int f();
};
class D : public B
{
private:
int f();
};
void f()
{
D d;
B* pb = &d;
D* pd = &d;
pb->f(); // OK: B::f() is public,
// D::f() is invoked
pd->f(); // error: D::f() is private
}
—end example]
Access is checked at the call point using the type of the expression used to denote the
object for which the member function is called (B* in the example above). The access of the member function in the class in which it was defined (D in the example above) is in general not known.
The key is the rest of your code. Only accept a BaseInterface* as an argument to any methods that require the doSomething() call. The client programmer is forced to derive from the interface to make his code compile.
This makes no sense to me. Regardless of which pointer you call doSomething(), you would still wind up with the method defined in most derived class. Consider the following scenario:
class BaseInterface
{
public:
virtual void doSomething() = 0;
~BaseInterface(){}
};
class Derived : public BaseInterface
{
public:
Derived() {}
~Derived(){}
virtual void doSomething(){}
private:
int x;
};
class SecondDerived : public Derived
{
public:
SecondDerived() {}
~SecondDerived(){}
private:
int x;
};
int main(int argc, char* argv[])
{
SecondDerived derived;
derived.doSomething(); //Derived::doSomething is called
BaseInterface* pInt = &derived;
pInt->doSomething(); //Derived::doSomething is called
return 0;
}