Inspired by this question, I’d like to know whether there is any trick (like SFINAE) to achieve the opposite.
Edit: Adding example
I have something like this (it is very simplified because it has a lot of details):
#include <iostream>
class Base {
public:
Base(){}
virtual ~Base(){
}
void initialize() { implementation(); }
private:
virtual void implementation() = 0;
};
class Derived : public Base {
private:
virtual void implementation() { std::cout << "initialization" << std::endl;}
};
int main() {
std::unique_ptr<Base> b(new Derived());
b->initialize();
return 0;
}
The initialize method must be called.
But if I put initialize method inside Base constructor it will call a pure virtual method.
I want to know if there is a way to prevent someone to use improperly the constructed object.
Edit: My “solution”:
#include <iostream>
class Base {
public:
virtual ~Base(){
}
Base() {};
private:
void initialize() { implementation(); }
virtual void implementation() = 0;
template<class DerivedType> friend Base *factory();
};
class Derived : public Base {
private:
Derived() {}
virtual void implementation() { std::cout << "initialization" << std::endl;}
template<class DerivedType> friend Base *factory();
};
template<class DerivedType>
static Base *factory(){
Base *b = new DerivedType();
b->initialize();
return b;
}
int main() {
std::unique_ptr<Base> b(factory<Derived>());
return 0;
}
You can’t force a compiler error, but there are other alternatives.
If an instance of your type is simply invalid unless initialize is called, and if documenting that fact or throwing an exception upon use if uninitialized is unacceptable, then you should make the constructor private and expose a static method to create instances of your type.
This way clients of your code simply cannot use an uninitialized instance of your type. If there is a better, more elegant approach I don’t know of it (but maybe someone around here does).