Is there a way in C++ to forbid code to compile if the specific function was not called.
Imagine I have some class:
class CExample
{
public:
void Init();
void DoWork();
};
Is there a way to forbid calling DoWork() if the Init() function was not called for class object?
I want to forbid writing such a code:
CExample e;
e.DoWork();
and permit this version:
CExample e;
e.Init();
e.DoWork();
Can I reach this behaviour somehow with metaprogramming?
You can just use a constructor instead of Init.
In his notes about exception safety in the standard library, as appendix to the 3rd edition of The C++ Programming Language, Bjarne Stroustrup discussed how using init functions is at odds with the notion of class invariant. It's generally Bad Practice™, mainly for that reason.
Some old GUI frameworks like Microsoft's MFC used init functions in order to do derived class specific initialization. There are other techniques to do that, including just passing the required information up the construction chain via arguments.
No, that would be bad design. If it must be called for the object to be usable, it should be called in the constructor. After an object is constructed, all public methods should be callable-- the object should be fully constructed and ready for use.
At compile time it is not known if Init() has been called before DoWork(). This can only be decided at runtime. Therefore metaprogramming will not be useful here.
You should put your init code into the constructor to enforce that the class is properly constructed. However if you really insist, and your init function really isn't polymorphic you can use CRTP with a protected constructor:
template <typename What>
class InitMe : public What
{
public:
InitMe() : What() { this->Init(); }
};
class CExample
{
public:
void Init() {}
void DoWork() {}
protected:
CExample() {}
};
int main()
{
//CExample e; // Error: protected constructor.
InitMe<CExample> e;
e.DoWork();
}
As Cheers and hth. -Alf and Rob K have both touched on, you most definitely want to have your init work performed in your class constructor. Having to call a separate function to ensure your class is properly ready is poor design.
However, that being said, you can detect if it's been called and act accordingly anyway:
void CExample::Init()
{
// things
...
init = true;
}
void CExample::DoWork()
{
if (!init)
{
Init();
}
}
Related
I was wondering if, in modern C++, there is a way to force invocation of base class method from the method that is currently overriding it.
Let's look at an example scenario like the following:
class Base
{
public:
virtual void initialize()
{
... initialization stuff common to all subclasses ...
}
};
class Derived
{
public:
virtual void initialize() override
{
Base::initialize(); // !! I can forget to do this!
... initialization stuff specific to Derived class ...
}
};
I wonder if there is a way to force (at compile time) the invocation of base method from derived method, in order to avoid to forget some important initialization stuff provided by base class.
A possible ugly solution, that I adopt now, is the following (a sort of basic usage of the template method design pattern):
class Base
{
public:
void initialize() // note: this is not virtual
{
... initialization stuff common to all subclasses ...
this->_innerInitialize();
}
protected:
virtual void _innerInitialize() // actual virtual method to be overridden by subclasses
{
}
};
class Derived
{
virtual void _innerInitialize() override
{
... initialization stuff specific to Derived class ...
}
};
Does modern C++ offers a more elegant way to enforce this mechanism? Thank you all in advance.
Edit: since a lot of people are focusing about the initialize() method, the question was more general, not just for initialization methods, although the separation of construction and initialization is sometimes useful (for example for wrapper objects that encapsulate OpenGL entities, where sometimes you have to delay the initialization to a moment where a valid OpenGL context is available).
If you have a feature rich class, possibly one you do not own/control, it is often the case where you want to add some functionality so deriving makes sense.
Occasionally you want to subtract as well, that is disallow some part of the base interface. The common idiom I have seen is to derive and make some member functions private and then not implement them. As follows:
class Base
{
public:
virtual void foo() {}
void goo() { this->foo(); }
};
class Derived : public Base
{
private:
void foo();
};
someplace else:
Base * b= new Derived;
and yet another place:
b->foo(); // Any way to prevent this at compile time?
b->goo(); // or this?
It seems that if the compilation doesn't know that it is derived, the best you can do is not implement and have it fail at runtime.
The issue arises when you have a library, that you can't change, that takes a pointer to base, and you can implement some of the methods, but not all. So part of the library is useful, but you run the risk of core dumping if you don't know at compile time which functions will call what.
To make it more difficult, others may inherit from you class and want to use the library, and they may add some of the functions you didn't.
Is there another way? in C++11? in C++14?
Let's analyze this, focused on two major points:
class Base
{
public:
virtual void foo() {} // This 1)
// ...
class Derived : public Base // and this 2)
In 1) you tell the world that every object of Base offers the method foo() publicly. This implies that when I have Base*b I can call b->foo() - and b->goo().
In 2) you tell the world that your class Derived publicly behaves like a Base. Thus the following is possible:
void call(Base *b) { b->foo(); }
int main() {
Derived *b = new Derived();
call(b);
delete b;
}
Hopefully you see that there is no way call(Base*) can know if b is a derived and thus it can't possibly decide at compile-time if calling foo wouldn't be legal.
There are two ways to handle this:
You could change the visibility of foo(). This is probably not what you want because other classes can derive from Base and someone wants to call foo afterall. Keep in mind that virtual methods can be private, so you should probably declare Base as
class Base
{
virtual void foo() {}
public:
void goo() { this->foo(); }
};
You can change Derived so that it inherits either protected or private from Base. This implies that nobody/only inheriting classes can "see" that Derived is a Base and a call to foo()/goo() is not allowed:
class Derived : private Base
{
private:
void foo() override;
// Friends of this class can see the Base aspect
// .... OR
// public: // this way
// void foo(); // would allow access to foo()
};
// Derived d; d.goo() // <-- illegal
// d.foo() // <-- illegal because `private Base` is invisible
You should generally go with the latter because it doesn't involve changing the interface of the Base class - the "real" utility.
TL;DR: Deriving a class is a contract to provide at least that interface. Subtraction is not possible.
This seems to be what you want to do:
struct Library {
int balance();
virtual int giveth(); // overrideable
int taketh(); // part of the library
};
/* compiled into the library's object code: */
int Library::balance() { return giveth() - taketh(); }
/* Back in header files */
// PSEUDO CODE
struct IHaveABadFeelingAboutThis : public Library {
int giveth() override; // my implementation of this
int taketh() = delete; // NO TAKE!
};
So that you can't call taketh() on an IHaveABadFeelingAboutThis even when it is cast as the base class.
int main() {
IHaveABadFeelingAboutThis x;
Library* lib = &x;
lib->taketh(); // Compile error: NO TAKE CANDLE!
// but how should this be handled?
lib->balance();
}
If you want to present a different interface than the underlying library you need a facade to present your interface instead of the that of the library.
class Facade {
struct LibraryImpl : public Library {
int giveth() override;
};
LibraryImpl m_impl;
public:
int balance() { return m_impl.balance(); }
virtual int giveth() { return m_impl.giveth(); }
// don't declare taketh
};
int main() {
Facade f;
int g = f.giveth();
int t = f.taketh(); // compile error: undefined
}
Although I don't think your overall situation is good design, and I share many of the sentiments in the comments, I can also appreciate that a lot of code you don't control is involved. I don't believe there is any compile time solution to your problem that has well defined behavior, but what is far preferable to making methods private and not implementing them is to implement the entire interface and simply make any methods you can't cope with throw an exception. This way at least the behavior is defined, and you can even do try/catch if you think you can recover from a library function needing interface you can't provide. Making the best of a bad situation, I think.
If you have class A:public B, then you should follow the https://en.wikipedia.org/wiki/Liskov_substitution_principle
The Liskov substitution principle is that a pointer-to-A can be used as a pointer-to-B in all circumstances. Any requirements that B has, A should satisfy.
This is tricky to pull off, and is one of the reasons why many consider OO-style inheritance far less useful than it looks.
Your base exposes a virtual void foo(). The usual contract means that such a foo can be called, and if its preconditions are met, it will return.
If you derive from base, you cannot strengthen the preconditions, nor relax the postconditions.
On the other hand, if base::foo() was documented (and consumers of base supported) the possibility of it throwing an error (say, method_does_not_exist), then you could derive, and have your implementation throw that error. Note that even if the contract says it could do this, in practice if this isn't tested consumers may not work.
Violating the Liskov substitution principle is a great way to have lots of bugs and unmaintainable code. Only do it if you really, really need to.
Since once cannot call a overwritten function of a derived class in base class constructor, I would like to emulate this behavior (similar to what C#, Java, ... are doing under the hood).
The most elegant I could come up with (from a signature side of view) is the following:
class Base {
protected:
virtual void init() {
}
template <typename T, typename ...U>
T internal_create(U&& u) {
T instance(std::forward<U>(u)...);
instance.init();
return instance;
}
};
class Derived : public Base {
protected:
Derived() = default;
virtual void init() override {
}
public:
static Derived create() {
return internal_create<Derived>();
}
};
Where create works as a substitute for the constructor (from public point of view) and the only way to instantiate an Object.
Question is whether this could be achieved simpler, since now every derived class has to implement create.
I can't see that your code would compile. And I can't see the point of the virtual init method there, although it does suggest two phase construction. Which is just evil, which you can find out more about by reading Bjarne Stroustrup’s appendix E to “The C++ Programming Language”, especially section E3.5.
The usual methods for doing derived class initialization in a base class constructor are outlined in the FAQ. Since I once convinced Marshall to add that FAQ item, I feel free to also direct you to my own blog.
In the future, remember that it is often a good idea to check out the FAQ first.
Oh, I forgot. The point about the C++ rules for dynamic type during construction, is to provide type safe construction. In Java and C# you can easily introduce a bug where you're accessing some uninitialized members of a derived class, but not in C++.
Two phase construction ditches that type safety, and makes it difficult to write exception safe usage code, in return for the ability to code it up cleanly for an early 1990's compiler (but really, who needs that ability).
The other usual solutions are designed to keep the type safety.
First of all, I searched this problem and found a lot of similiar questions, but I couldn't find an answer that fixed my problem. I am very sorry if that is just me being dumb.
What I am trying to do is make the constructor of an abstract class call a function that is pure virtual. In Java, this works, because the subclass provides the implementation of the abstract method that is called. However, in C++, I get this linker error:
test.o:test.cpp:(.text$_ZN15MyAbstractClassC2Ev[MyAbstractClass::MyAbstractClass
()]+0x16): undefined reference to `MyAbstractClass::initialize()'
collect2: ld returned 1 exit status
Here is my code:
#include <iostream>
class MyAbstractClass {
protected:
virtual void initialize() = 0;
public:
MyAbstractClass() {
initialize();
}
};
class MyClass : public MyAbstractClass {
private:
void initialize() {
std::cout << "yey!" << std::endl;
}
};
int main() {
MyClass *my = new MyClass();
return 0;
}
As a further explanation of what I am trying to do, here is code in Java that achieves my goal:
public abstract class MyAbstractClass {
public MyAbstractClass() {
initialize();
}
protected abstract void initialize();
}
public class MyClass extends MyAbstractClass {
protected void initialize() {
System.out.println("Yey!");
}
public static void main(String[] args) {
MyClass myClass = new MyClass();
}
}
This code prints "Yey!". Any help much appreciated!
MyAbstractClass() {
initialize();
}
That will not perform a virtual dispatch to MyClass::initialize(), because at this stage of the object's construction its MyClass parts haven't been created yet. Thus you really are invoking MyAbstractClass::initialize() and, as such, it must be defined. (Yes, pure virtual member functions can be defined.)
Try to avoid invoking virtual member functions from constructors, because this sort of stuff will happen and catch you out. It rarely makes sense to do it.
Also, try to avoid initialize() functions; you already have constructors to play with.
Update
Actually, though you may take the above as read for any other virtual member function, invoking a pure virtual member function from the constructor yields Undefined Behaviour. So don't even try!
In C++, you can't call a pure virtual function from a constructor or destructor (even if it has a definition). If you call a non-pure one, then it will be dispatched as if the object's type were the class under construction, so you'll never be able to call a function defined in a derived class.
In this case, you don't need to; the derived class's constructor will be called after the base class's, so you get the desired result from:
#include <iostream>
class MyAbstractClass {
public:
MyAbstractClass() {
// don't do anything special to initialise the derived class
}
};
class MyClass : public MyAbstractClass {
public:
MyClass() {
std::cout << "yey!" << std::endl;
}
};
int main() {
MyClass my;
return 0;
}
Note that I also changed my to an automatic variable; you should get in the habit of using them whenever you don't need dynamic allocation, and learn how to use RAII to manage dynamic resources when you really do need them.
Let me quote Scott Meyers here (see Never Call Virtual Functions during Construction or Destruction):
Item 9: Never call virtual functions during construction or destruction.
I'll begin with the recap: you shouldn't call virtual functions during construction or destruction, because the calls won't do what you think, and if they did, you'd still be unhappy. If you're a recovering Java or C# programmer, pay close attention to this Item, because this is a place where those languages zig, while C++ zags.
The issue: during object construction the virtual function table might not yet be ready. Just imagine that your class is eg. fourth in line of inheritance. Constructors are called in inheritance order, so while calling this pure virtual (or even if it was non-pure) you would like the base class to call initialize for an object that is not yet complete!
The C++ side has been handled in other answers, but I want to add a remark on the Java side of it. Calling a virtual function from a constructor is a problem in all cases, not just in C++. Basically what the code is trying to do is execute a method on an object that has not yet been created and that is an error.
The two solutions implemented in the different languages differ in trying to make some sense of what your code is trying to do. In C++ the decision is that during construction of a base object, and until construction of the derived object starts, the actual type of the object is base, which means that there won't be dynamic dispatch. That is, the type of the object at any time is that of the constructor being executed[*]. While this is surprising to some (you among others), it provides a sensible solution to the problem.
[*] Conversely the destructor. The type also changes as the most derived constructors complete.
The alternative in Java is that the object is of the final type from the beginning, even before construction has completed. In Java, as you demonstrated, the call will be dispatched to the final overrider (I am using C++ slang here: to the last implementation of the virtual function in the execution chain), and that can cause unwanted behavior. Consider for example this implementation of initialize():
public class MyClass extends MyAbstractClass {
final int k1 = 1;
final int k2;
MyClass() {
k2 = 2;
}
void initialize() {
System.out.println( "Constant 1 is " + k1 + " and constant 2 is " + k2 );
}
}
What is the output of the previous program? (Answer at the bottom)
More than just a toy example, consider that MyClass provides some invariants that are set at construction time and hold for the whole lifetime of the object. Maybe it holds a reference to a logger on which data can be dumped. By looking at the class, you can see that the logger is set in the constructor and assume that it cannot be reset anywhere in the code:
public class MyClass extends MyAbstractClass {
Logger logger;
MyClass() {
logger = new Logger( System.out );
}
void initialize() {
logger.debug( "Starting initialization" );
}
}
You probably see now where this is going. By looking at the implementation of MyClass there does not seem to be anything wrong at all. logger is set in the constructor, so it can be used in all methods of the class. Now the problem is that if MyAbstractClass calls on a virtual function that gets dispatched then the application will crash with a NullPointerException.
By now I hope that you understand and value the C++ decision of not performing dynamic dispatch and thus avoid executing functions on objects that have not yet been fully initialized (or conversely have already been destroyed, if the virtual call is in the destructor).
(Answer: this might depend on the compiler/JVM, but when I tried this long long time ago, the line printed Constant 1 is 1 and constant 2 is 0. If you are happy with that, fine by me, but I found that to be surprising... The reason for the 1/0 in that compiler is that the process of initialization first sets the values that are in the variable definition, and then calls the constructors. This means that the first step of construction would set k1 before calling MyAbstractBase constructor, that would call initialize() before MyBase constructor has run and set the value of the second constant).
During construction and destruction, the virtual table is set up appropriately for the base subobject being constructed or destroyed. This is the theoretically correct thing to do, because the more-derived class is not alive (its lifetime either hasn't yet started or has already ended).
As already explained by #Seth, you cannot call virtual functions in a constructor. More specifically, the virtual dispatch mechanism is disabled during construction and destruction. Either make your initialize member function nonvirtual and implement it in the base class, or have the user call it explicitly.
Yes i know the phrase "virtual constructor" makes no sense but i still see articles like this
one: http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=184
and i'v heard it mentioned as a c++ interview.
What is the general consensus?
Is a "Virtual Constructor" good practice or something to be avoided completely?
To be more more precise, can some one provide me with a real world scenario where they have had to use it, from where i stand this concept of virt. constr. is a somewhat useless invention but i could be wrong.
All the author has done is implement prototyping and cloning. Both of which are powerful tools in the arsenal of patterns.
You can actually do something a lot closer to "virtual constructors" through the use of the handle/body idiom:
struct object
{
void f();
// other NVI functions...
object(...?);
object(object const&)
object& operator = (object const&);
~object();
private:
struct impl;
impl * pimpl;
};
struct object::impl
{
virtual void f() = 0;
virtual impl* clone() = 0;
// etc...
};
struct impA : object::impl { ... };
struct impB : object::impl { ... };
object::object(...?) : pimpl(select_impl(...?)) {}
object::object(object const& other) : pimpl(other.pimpl->clone()) {}
// etc...
Don't know if anyone has declared this an Idiom but I've found it useful and I'm sure others have come across the same idea themselves.
Edit:
You use factory methods or classes when you need to request an implementation for an interface and do not want do couple your call sites to the inheritance tree behind your abstraction.
You use prototyping (clone()) to provide generic copying of an abstraction so that you do not have to determine type in order to make that copy.
You would use something like I just showed for a few different reasons:
1) You wish to totally encapsulate the inheritance relation behind an abstraction. This is one method of doing so.
2) You want to treat it as a value type at the abstract level (you'd be forced to use pointers or something otherwise)
3) You initially had one implementation and want to add new specifications without having to change client code, which is all using the original name either in an auto declaration or heap allocation by name.
The best way to write "virtual constructors" is to use a Prototype pattern with a Clone() virtual method wich calls the copy constructor of the real type of the object and returns a pointer to a base class.
class Base
{
public:
virtual Base* Clone() { return new Base(*this); }
};
class Derived : public Base
{
virtual Base* Clone() { return new Derived(*this); }
};
It's not considered a good practice and is to use only if you need it (implement a copy-paste function for example)
I consider these so-called "virtual constructors" a bad design when used instead of constructors. These are nothing but virtual functions that are supposed to be called at the beginning of use of an instance of a class.
From the link you've posted:
class Browser
{
public:
//virtual default constructor
virtual Browser* construct() {return new Browser;}
};
Let's add a member field:
class Browser
{
int member;
public:
//virtual default constructor
virtual Browser* construct() {return new Browser;}
};
We need to initialize the member field, how do we do it?
class Browser
{
int member;
public:
//virtual default constructor
virtual Browser* construct()
{
Browser* b = new Browser;
b->member = 0;
return b;
}
};
Consider a situation when someone forgets to use template <class T> void func(T & obj) and does something like this:
Browser b;
printf("member=%d", b.member);
This way an uninitialized field is used. There is no way to prevent it.
Now, in this case
class Browser
{
int member;
public:
Browser() : member(0) { }
virtual Browser* construct() { /* some init stuff */ return new Browser;}
};
the default constructor is always used and member field always initialized.
However calling the construct() a "virtual constructor" I consider a naming abuse.
The pattern I showed above is quite common eg. in MFC. CWnd and similar classes use constructors to init instances and Create(...) functions to fully init and create controls. I would never call the Create(...) function a "virtual constructor", anyway.
It's something you can use, but only when you really, really need it. Even the guy in the link said that it's only something that you use if desperate.
All the answer above doesn't answer the question but are giving some workaround. The answer to the above question is http://www.stroustrup.com/bs_faq2.html#virtual-ctor straight from the language author itself. In short it says you need complete information to construct an object, hence virtual constructor doesn't exist in C++.