I need to use C++. C++11 would be interesting, but I'd prefer without. I have the following class structure.
class Wheel { /*...*/ };
class MtbWheel : public Wheel { /*...*/ };
class Bike { Wheel front_wheel; };
class Mountainbike : public Bike { MtbWheel front_wheel; };
Now, this completely works: The Mountainbike overrides front_wheel, and thus can use an MtbWheel. Softwaretechnically, I am not happy, though.
What I would prefer is disallowing to override front_wheel, or at least restrict overwriting by classes that do not inherit class Wheel.
Instead of overriding front_wheel, I'd like only to "add" properties to it.
EDIT: Is there a solution without virtual functions, but with templates instead?
Your front_wheel member in Mountainbike class does not override front_wheel, it hides it. Mountainbike class actually has two front_wheel members, but the one from the Bike class is hidden by the one declared in Mountainbike. Meaning that if Bike accesses front_wheel, it will access an object of type Wheel, while when Mountainbike accesses front_wheel, it will access an object of type MtbWheel - but these two wheel objects don't know of each other!
Better OO design would be to make front_wheel e.g. a pointer in Bike (or even better a smart pointer), and initialize it in the constructor of Mountainbike to hold an object of a class derived from Wheel which fits best to Mountainbike. That way, when accessing front_wheel, one way or the other virtual functions come into play of course.
An alternative solution, as per Steve Jessop's suggestion in the comments below, making use of templates instead of using polymorphism, would be:
class Wheel { /*...*/ };
class MtbWheel : public Wheel { /*...*/ };
template <typename WheelType>
class Bike { WheelType front_wheel; };
class Mountainbike : public Bike<MtbWheel> { /* ... */ };
That way, no virtual functions are involved when operating on front_wheel. There are some points to consider with such a solution, however:
For each different WheelType you use Bike with, separate code will be created; if you have many different such types, this might result in code bloat.
If you have more than one class derived from Bike with different WheelType parameters, they do not have the same base class (see Steve Jessop's comment, and point 1), and therefore also can't be accessed polymorphically.
You can not enforce an explicit interface on the WheelType being passed as template parameter to Bike; only the implicit interface is defined by the methods and members used from Bike. That should be no problem however, since the compiler can still verify that implicit interface.
You're not overriding anything. There is still a Wheel front_wheel; in your derived class. You can access it through m.Bike::front_wheel, or something like that. If you want derived classes to provide their own instantiations of front_wheel, then you will need to only provide a virtual accessor in the base class and let derived classes create their own.
The variable front_wheel is not overriden - it is just hidden. The member variable Wheel front_wheel is still in the Mountainbike class. So actually there are two variables named front_wheel in Mountainbike. But to access the hidden variable in Mountainbike you would need to say it explicitly: Bike::front_wheel.
A better way of doing what you want is to create an interface class with no data:
class Bike {
public:
virtual Wheel const &getFronWheel() const = 0;
virtual ~Bike() {}
};
and then derive any specific bike from that:
class RegularBike: public Bike {
public:
virtual Wheel const &getFronWheel() const { return wheel; }
private:
Wheel wheel;
}
class MtbBike: public Bike {
public:
virtual MtbWheel const &getFronWheel() const { return wheel; }
private:
MtbWheel wheel;
}
Edit: Without using virtuality, but templates instead:
template<typename WheelType>
class Bike {
public:
/* Common methods for any bike...*/
protected: // or private
WheelType wheel;
};
Then you can extend the Bike as you wish:
class RegularBike: public Bike<Wheel> {
/* Special methods for regular bike...*/
};
class MtbBike: public Bike<MtbWheel> {
/* Special methods for Mtb bike...*/
};
You can create a interface of IWheel instead of Class Wheel.
Create OverRide method in MtbWheel class. So that whoever wants to override this method can override this method else use the default method which we have implemented in MtbWheel class. By using this you can add properties of it.
The solution is to not do that. Writing a derived class requires careful study of the base class, followed by careful design. Magic cookies are no substitute for knowledge and thought. And, yes, I've made my share of this kind of mistake, and kicked myself for being careless.
Related
I have created two classes A and B where B inherits from class A. As you can see, I have a vector in class A that is currently under the protected section of the class. I am unsure if using protected is bad practice?
#include <vector>
class A
{
public :
A();
protected:
std::vector <std::string> a;
};
class B : A
{
public :
B();
void accessVector()
{
a.size();
}
private:
};
When A makes a data member a protected, it is offering the following guarantee to all classes that derive from it:
"You may do anything you like to a without telling me. This includes appending to it, modifying its contents, removing items, sorting it, moving from it, moving to it and otherwise making its state undefined and/or unknowable to me".
Remember that anyone may create a class that derives from A.
For this reason, to all intents and purposes, a protected member is a public member, since a derived class may simply say the following:
public:
using A::a;
Starting here and working forward, you'll find that there are only two sensible use-cases for protected:
When a base class defines a virtual member function that may need to be called from an overridden version of the same function in a derived class.
When the base class wants to expose 'data as interface' to a derived class, but not to the world.
I have following dilemma:
I have a full abstract class. Each inheriting class will need 3 same parameters. Each of them will additionally need other specific parameters.
I could:
1) implement a common constructor for initializing 3 common parameters in my base class, but then I have to make non-abstract getters for corresponding fields (they are private).
OR
2) leave my base class abstract and implement constructors in inherited classes, but then I have to make it in each class fields for common parameters.
Which is a better approach? I don't want to use protected members.
An abstract class is one who has at least one pure virtual (or, as you call it, abstract) function. Having non-abstract, non-virtual functions does not change the fact that your class is abstract as long as it has at least one pure virtual function. Go for having the common functionality in your base class, even if it is abstract.
One way to avoid code duplication without polluting your abstract interface with data members, is by introducing an additional level of inheritance:
// Only pure virtual functions here
class Interface {
public:
virtual void foo() = 0;
};
// Things shared between implementations
class AbstractBase : public Interface {
};
class ImplementationA : public AbstractBase {
};
class ImplementationB : public AbstractBase {
};
If your class looks like this, a pure abstract class:
class IFoo {
public:
virtual void doThings() = 0;
}
class Foo {
public:
Foo(std::string str);
void doThings() override;
}
The value your inheritance has is to provide you with the oppurtunity to subsitute Foo with another at runtime, but hiding concrete implementations behind interfaces. You can't use that advantage with Constructors, there's no such thing as a virtual constructor (that's why things like the Abstract Factory Pattern exist). All your implementations of Foo take a std::string and all your implementations of doThings use that string? Great, but that's a coincidence not a contract and doesn't belong in IFoo.
Lets talk about if you've created concrete implementations in IFoo, so that it's a abstract class and not a pure abstract class (IFoo would be a bad name now btw). (*1) Lets assume using inheritance to share behaviour was the correct choice for you class, which is sometimes true. If the class has fields that need to be initialised create a protected constructor (to be called from every child implementation) and remove/ommit the default one.
class BaseFoo {
private:
std::string _fooo;
protected:
BaseFoo(std::string fooo) : _fooo(fooo) {}
public:
virtual void doThings() = 0;
std::string whatsTheBaseString() { return _fooo;}
}
Above is the way you correctly pass fields needed by a base class from the child constructor. This is a compile time guarantee that a child class will 'remember' to initialize _fooo correctly and avoids exposing the actual member fooo to child classes. Trying to initialize _fooo in all the child constructors directly would be incorrect here.
*1) Quickly, why? Composition may be a better tool here?.
In C++, if I have a class Base which is a private base class of Derived but Base has no virtual functions, would it be cleaner to instead replace having inheritance with encapsulation in class Encapsulate? I imagine the only benefit to inheritance in this case would be that the base class can be accessed directly in the derived class as opposed to through memberVariable. Is one or the other practice considered better, or is it more of a personal style question?
class Base {
public:
void privateWork();
// No virtual member functions here.
};
class Derived : Base {
public:
void doSomething() {
privateWork();
}
};
class Encapsulate {
Base memberVariable;
public:
void doSomething() {
memberVariable.privateWork()
}
};
Remember that inheritance models "Liskov substitution": Foo is a Bar if and only if you can pass a Foo variable to every function expecting a Bar. Private inheritance does not model this. It models composition (Foo is implemented in terms of Bar).
Now, you should pretty much always use the second version, since it is simpler and expresses the intent better: it is less confusing for people who don't know about it.
However, sometimes, private inheritance is handy:
class FooCollection : std::vector<Foo>
{
public:
FooCollection(size_t n) : std::vector<Foo>(n) {};
using std::vector<Foo>::begin;
using std::vector<Foo>::end;
using std::vector<Foo>::operator[];
};
This allows you to reuse some of the functionality of vector without having to forward manually the 2 versions (const + non const) of begin, end, and operator[].
In this case, you don't have polymorphism at all: this is not inheritance, this is composition is disguise; there is no way you can use a FooCollection as a vector. In particular, you don't need a virtual destructor.
If there are no virtual functions, then inheritance should not be used in OO. Note this does not mean that it must not be used, there are a few (limited) cases where you might need to (ab)use inheritance for other purposes than OO.
I was wondering whether a design pattern or idiom exists to automatically register a class type. Or simpler, can I force a method to get called on a class by simply extending a base class?
For example, say I have a base class Animal and extending classes Tiger and Dog, and I have a helper function that prints out all classes that extend Animal.
So I could have something like:
struct AnimalManager
{
static std::vector<std::string> names;
static void registerAnimal(std::string name) {
//if not already registered
names.push_back(name); }
};
struct Animal
{
virtual std::string name() = 0;
void registerAnimal() { AnimalManager::registerAnimal(name()); }
};
struct Tiger : Animal
{
virtual std::string name() { return "Tiger"; }
};
So basically I would do:
Tiger t;
t.registerAnimal();
This could be worked into a static function as well. Is there any pattern (like a curiously recursive template) or something like that that can help me achieve this without explicitly having to call the registerAnimal method.
I want my class Animal to be extendible in the future and others might forget to call register, I'm looking for ways to prevent that besides documenting this (which I will anyway).
PS This is just an example, I'm not actually implementing animals.
You can indeed do this using the curiously recursive template idiom. It requires nothing from whoever is extending the class that can't be enforced by the compiler:
template<class T>
struct Animal
{
Animal()
{
reg; //force specialization
}
virtual std::string name() = 0;
static bool reg;
static bool init()
{
T t;
AnimalManager::registerAnimal(t.name());
return true;
}
};
template<class T>
bool Animal<T>::reg = Animal<T>::init();
struct Tiger : Animal<Tiger>
{
virtual std::string name() { return "Tiger"; }
};
In this code, you can only extend Animal if you specialize it. The constructor forces the static member reg to be initialized, which in turn calls the register method.
EDIT: As pointed out by #David Hammen in the comments, you won't be able to have a collection of Animal objects. However, this can easily be solved by having a non-template class from which the template inherits and use that as a base class, and only use the template for extending.
If you insist every animal should be registered, why not just make name a parameter of Animal constructor. Then you can put register issues to Animal constructor and every derived will have to pass valid name and register:
struct Animal
{
Animal(std::string name){ AnimalManager::registerAnimal(name);}
}
struct Tiger : Animal
{
Tiger():Animal("Tiger"){}
};
This is a typical example where you want to do some sort of bookkeeping when an object is constructed. Item 9 in Scott Meyers "Effective C++" gives an example of this.
Basically you move all the bookkeeping stuff to base class. Derived class explicitly constructs base class and passes the information that is required for Base class construction. For example:
struct Animal
{
Animal(std::string animal_type)
{
AnimalManager::registerAnimal(animal_type);
};
};
struct Dog : public Animal
{
Dog() : Animal(animal_type()) {};
private:
static std::string animal_type()
{
return "Dog";
};
};
Usually I do this with a macro.
Unit test frameworks often employ the technique for registering the tests, e.g. GoogleTest
#AMCoder: This is not the answer you want. The answer you want, reflection (e.g., what_am_I()) doesn't really exist in C++.
C++ has in a rather limited form via the RTTI. Using RTTI in the base class to determine the "true" type of the object being constructed won't work. Calling typeid(*this) in a base class will instead give you the typeinfo for the class being constructed.
You can make your class Animal have a non-default constructor only. This works fine for classes that derive directly from Animal, but what about classes that derive from a derived class? This approach either precludes further inheritance or requires class builders to create multiple constructors, one of which is for use by derived classes.
You can use Luchian's CRTP solution, but this too has problems with inheritance, and it also precludes you from having a collection of pointers to Animal objects. Add that non-template base class back into the mix so you can have a collection of Animals and you have the original problem all over again. Your documentation will have to say to only use the template to make a class that derives from Animal. What happens if someone doesn't do that?
The easiest solution is the one you don't like: Require that every constructor of a class that derives from Animal must call register_animal(). Say so in your documentation. Show the users of your code some examples. Put a comment in front of that example code, // Every constructor must call register_animal(). People who use your code are going to use cut and paste anyhow, so have some cut-and-paste ready solutions on hand.
Worrying about what happens if people don't read your documentation is a case of premature optimization. Requiring that every class call register_animal() in their constructors is a simple requirement. Everyone can understand it and everyone can easily implement it. You've got much bigger troubles on your hands with your users than a failed registration if your users can't even follow this simple instruction.
You could just call a method in the base class constructor, which will get called everytime a derived class gets instantiated, as follows:
class Animal {
public:
Animal() {doStuff();}
}
The doStuff() method could be implemented in the base class to do static operations, or it could be pure virtual and be implemented in derived classes.
Edit: As correctly pointed out in the comments, virtual methods cant be called in the ctor.
Notice though that the base class constructor will be called before the derived constructors, so you could also do something like this:
class Animal {
public:
Animal(const std::string &name) {doStuff(name);}
private:
Animal(); // Now nobody can call it, no need to implement
}
class Dog : public Animal {
Dog() : Animal("Dog") {}
}
Hope that helps
I was wondering if there is a way to declare an object in c++ to prevent it from being subclassed. Is there an equivalent to declaring a final object in Java?
From C++ FAQ, section on inheritance
This is known as making the class
"final" or "a leaf." There are three
ways to do it: an easy technical
approach, an even easier non-technical
approach, and a slightly trickier
technical approach.
The (easy) technical approach is to
make the class's constructors private
and to use the Named Constructor Idiom
to create the objects. No one can
create objects of a derived class
since the base class's constructor
will be inaccessible. The "named
constructors" themselves could return
by pointer if you want your objects
allocated by new or they could return
by value if you want the objects
created on the stack.
The (even easier) non-technical
approach is to put a big fat ugly
comment next to the class definition.
The comment could say, for example, //
We'll fire you if you inherit from
this class or even just /*final*/
class Whatever {...};. Some
programmers balk at this because it is
enforced by people rather than by
technology, but don't knock it on face
value: it is quite effective in
practice.
A slightly trickier technical approach
is to exploit virtual inheritance.
Since the most derived class's ctor
needs to directly call the virtual
base class's ctor, the following
guarantees that no concrete class can
inherit from class Fred:
class Fred;
class FredBase {
private:
friend class Fred;
FredBase() { }
};
class Fred : private virtual FredBase {
public:
...
};
Class Fred can access FredBase's ctor,
since Fred is a friend of FredBase,
but no class derived from Fred can
access FredBase's ctor, and therefore
no one can create a concrete class
derived from Fred.
If you are in extremely
space-constrained environments (such
as an embedded system or a handheld
with limited memory, etc.), you should
be aware that the above technique
might add a word of memory to
sizeof(Fred). That's because most
compilers implement virtual
inheritance by adding a pointer in
objects of the derived class. This is
compiler specific; your mileage may
vary.
No, there isn't really a need to. If your class doesn't have a virtual destructor it isn't safe to derive from it anyway. So don't give it one.
You can use this trick, copied from Stroustrup's FAQ:
class Usable;
class Usable_lock {
friend class Usable;
private:
Usable_lock() {}
Usable_lock(const Usable_lock&) {}
};
class Usable : public virtual Usable_lock {
// ...
public:
Usable();
Usable(char*);
// ...
};
Usable a;
class DD : public Usable { };
DD dd; // error: DD::DD() cannot access
// Usable_lock::Usable_lock(): private member
In C++0x (and as an extension, in MSVC) you can actually make it pretty clean:
template <typename T>
class final
{
private:
friend T; // C++0x, MSVC extension
final() {}
final(const final&) {}
};
class no_derived :
public virtual final<no_derived> // ah, reusable
{};
NO.
The closest you can come is to declare the constructors private, then provide a static factory method.
There is no direct equivalent language construct for this in C++.
The usual idiom to achieve this technically is to declare its constructor(s) private. To instantiate such a class, you need to define a public static factory method then.
As of C++11, you can add the final keyword to your class, eg
class CBase final
{
...
The main reason I can see for wanting to do this (and the reason I came looking for this question) is to mark a class as non subclassable so you can safely use a non-virtual destructor and avoid a vtable altogether.
There is no way really. The best you can do is make all your member functions non-virtual and all your member variables private so there is no advantage to be had from subclassing the class.