Does it make sense to have a class without constructor? - c++

I am wondering whether it makes sense to have a class without constructor if the derived classes have one. If not, is there a way of doing what I want differently?
My case is the following:
I want the users to only use the derived classes, but those have data members and methods in common.
EDIT: as default constructors exist for classes, it means that the user can always create an instance of Instrument directly, then how can I do what I want?
class instrument{
public:
double get_price();
std::string get_udl();
private:
double m_price;
std::string m_udl;
};
class stock : public instrument{
public:
double get_dividend();
private:
double m_dividend;
};
class option : public instrument{
public:
double get_strike();
private:
double m_strike;
};

I want the users to only use the derived classes, but those have data members and methods in common
Have your default (or any other) c'tor, but declare it with protected access. Now only derived classes may invoke it. Effectively making it usable only when inherited.
class instrument{
public:
double get_price();
std::string get_udl();
protected:
instrument() = default;
private:
double m_price;
std::string m_udl;
};
This also avoids the overhead associated with making a class abstract. If you don't need polymorphism, you shouldn't use it just to make a class usable only as a base class.

Have thought of Abstract class ?
An abstract class is a class that is declared abstract—it may or may not include abstract methods. Abstract classes cannot be instantiated, but they can be subclassed.
Isn't this what you are looking for ?

When there's no default constructor defined, the compiler will automatically generate one for you, doing nothing for members of basic types and calls the default constructor for members of struct/class types.
So the conclusion is, it makes no sense to have a class without any constructor because whenever you define an instance of that class you have to call at least one (more may be called with deligate construction).

Yes! Definitely it make sense. Because when user create the instance of derived class, first of all parent class's constructor will be called from within the derived class constructor. Even without you explicitly call it. And parent class's default constructor will be called even if you didn't create one. By default
public constructor with no parameter is present in every class
if it has no overridden constructor.
And yes all the public members of parent class will be present in derived class after creating derived class instance.

Related

What can possible use of making a class friend and inheriting it also?

I was going through one of my local libraries and noticed the follwowing:
class Derived : public Base
{
friend class Base; // serves as a factory
protected:
pthread_spinlock_t allocLock;
bool isSafe{ true };
Derived();
char *funcA() override;
public:
void funcB( bool _in ) override;
virtual ~Derived();
};
I am not able to understand if Base has been inherited then why it has been made a friend of Derived. Also how the comment serves as a factory make sense here?
If it were to access Base function, :: operator would have been sufficient.
Is it more related to Design approach?
Making the base class a friend gives the base class access to the private members of the derived class. It is hard to tell what the reason for this is here without seeing the definition of class Base. The comment seems to indicate that the base class has member functions to create objects of the derived classes.
Generally, this is bad design. It is a bad thing when the base class knows about its derived classes at all, and it is even worse when it has access to the derived classes' private members. The dependencies should only go one way: derived classes depend on the base class, not the other way around. In other words, a change in the derived class should not break the base class.
If you need a factory, the right way to do this is to put the creation logic into a separate factory class, not into the base class.

C++: where to place constructor in inheritance chain?

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?.

Which protected variable used in inheritance?

Suppose I have a Base class and its derived class Derived as follows:
class Base{
private:
_privateVar;
protected:
protectedVar;
public:
publicVar;
void publicMethod(someValue, anotherValue)
{
protectedVar = someValue;
publicVar = anotherValue;
}
};
class Dervied: public Base{
protected:
protectedVar:
};
int main(void)
{
Dervied d;
d.publicMethod(valueA, valueB);
}
My question-
When I call d.publicMethod(...), does the protectedVar in Derived get set or the one in Base class?
Thanks
--A
It is of Base class. Base class cannot access derived class members.
When I call d.publicMethod(...), does the protectedVar in Derived get set or the one in Base class?
The method is a member of the Base class and hence it can access only the members of the Base class.
If the method belonged to your Derived class, then it would access Derived class member.
Because Derived class data members always hide Base class data members when accessed inside their own member functions.
You cannot override a member variable, you can create another different variable in a different level in the hierarchy that has the same name, but they will be two unrelated variables. Within the context of the use of the variable, lookup will find one or the other and that is the one that will be picked up and used.
Polymorphism only applies to virtual member functions, not to non-virtual functions, not to member variables either.
Since publicMethod is a methoc of the Base class, the protectedVar of the base class is set.
I don't know if this is what you want or expect, but even if this is what you want, I think it is not advised to do it like this. Tools like PC-LINT will probably also warn you about such a construction.
The member in the base class is modified. Data members never behave as if they are virtual.
When the compiler reaches the definition of Base::publicMethod, it has to statically resolve all the names it uses. At that point, the only possible resolution of those names are the members of Base, so the generated code will access those members.
Subclassing Base later on does not, and could not possibly, go back and change the code generated for Base::publicMethod. The derived class could be in a different translation unit, or in a dynamically-loaded library.
If you want dynamic lookup, access protectedVar via a protected virtual accessor function: that would allow a derived class to interpose its own storage for the variable.
If Base::protectedVar and Derived::protectedVar have the same type anyway, it's hard to see what you expect to gain, but it would look like:
class Base
{
Type protectedVarImpl;
protected:
virtual Type & protectedVar();
virtual Type const & protectedVar() const;
public:
void publicMethod(someValue, anotherValue)
{
protectedVar() = someValue; // Note the method call
publicVar = anotherValue;
}
};
Type& Base::protectedVar() { return protectedVarImpl; }

Why does a purely virtual/abstract class require a constructor, in particular for protected const member variables?

I have a purely virtual class defined as such:
class BaseClass {
protected:
const int var;
public:
void somefun() = 0; // what I mean by a purely virtual class
// stuff...
};
If I don't add a constructor defined as such:
BaseClass(const int & VAR) : var(VAR) {};
that I would have to subsequently use in ever derived class, my derived class can't initialize the const variable var to whichever value it wants to. Now I actually understand what's going on here. Before constructing a derived class, a constructor of the base class is called, at which point const member variables must be initialized. My question is not a "how do I make my code work" kind of question, that's already been done. My question is about why the compiler thinks it's necessary. For a purely virtual class, shouldn't I be allowed to write something like:
class DerivedClass : BaseClass {
public:
DerivedClass() : var(SOME_VALUE) {};
}
If the compiler knows that a call to a BaseClass constructor will necessarily be followed by a call to some derived class constructror (since an object of abstract type can never be instantiated) shouldn't it give us a bit more leeway?
Is this all a consequence of how C++ chooses to get around the Diamond problem? Even if that was the case, shouldn't the compiler at least somehow allow for the possibility that const member variable of purely virtual functions will be defined in derived classes? Is that too complicated or does that mess with the C++ solution to the Diamond problem?
Thanks for the help everyone.
It's not "purely virtual" (whatever you mean by that) - it contains a data member.
Class members can only be initialised by the initialiser list of a constructor of that class, not of a derived class. That's how object initialisation is specified: all members that are initialised, are initialised before the constructor body begins.
Constant objects must be initialised, since they can't be assigned a value later.
Therefore, a class with a constant data member must initialise it in each constructor.
For a purely virtual class, shouldn't I be allowed to write something
like
No, but you can(and in this case should) write something like this:
class DerivedClass : BaseClass {
public:
DerivedClass() : BaseClass(SOME_VALUE) {};
};
The construction of an object occurs in a specific order. The base class must be fully constructed before the constructor of a derived class is run, so that the derived constructor is working with a fully formed and valid base object. If the initialization of base member variables were put off until the construction of the derived class, this invariant would be broken.

C++ object without subclasses?

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.