Concrete class not being constructed - c++

I have a class hierarchy like this:
class Base {
public:
virtual bool foo() const = 0;
static Base& getHeadInstance();
};
class Concrete: public Base {
public:
explicit Concrete(Base& f): fwd(f) {}
// ... other member functions elided
bool foo() const override { return /* some calculation */ && fwd.foo(); }
private:
Base& fwd;
};
so that I can construct a series of instances like this:
Concrete c1(Base::getHeadInstance());
Concrete c2(c1);
Concrete c3(c2);
so that c3 can make decisions and possibly defer to c2, which in turn could defer to c1 and so on like the Chain of Responsibility pattern.
The problem is that c2 and c3 are not constructed correctly and their fwd member always refers to Base::getHeadInstance().
What is going wrong here and what is the fix for this?
Update:
It doesn't matter what the static member returns. Pretend it returns an instance of this:
class Head: public Base {
public:
Head() = default;
private:
bool foo() const override { return true; }
};
Base& Base::getHeadInstance(){ static Head head; return head; }

I've had this same problem before. It boils down to overload resolution on your custom constructor Derived(Base&) vs the implicitly defined copy constructor Derived(const Derived&);, where the implicit copy constructor simply wins. Deleting it does not fix this, it still participates in overload resolution (but it does stop the wrong thing from happening silently).
Here is a reduced example:
struct Base
{
virtual ~Base();
};
struct Derived : Base
{
Derived(Base&);
Derived(const Derived&); // Implicitly or explicitly declared in any case.
};
Derived getDerived();
void test()
{
Derived d1 = getDerived();
Derived d2(d1); // copies
}
https://godbolt.org/z/aoJFlC
There are several ways to get the code to do what you want the way you've written it (see other answers), but I would like to point out that you should take special care to save the next reader of your code from this same confusion you had. A cast to Base&, repurposed copy constructor semantics or something like using Derived(Base*); will all raise questions in future readers. You can try to solve that through documentation, but chances are somebody misses that and becomes confused. I would suggest making the intent as explicit and visible as possible, for example like this:
enum class ConstructFromBase { Tag };
struct Derived : Base
{
Derived(Base&, ConstructFromBase);
Derived(const Derived&) = delete;
};
Derived getDerived();
void test()
{
Derived d1 = getDerived();
Derived d2(d1, ConstructFromBase::Tag);
}
https://godbolt.org/z/QfeuAM
That should communicate the intent very clearly and costs virtually nothing. (There are many other ways to write and name such a tag, mine is probably not the most canonical...)

You have an implicit copy constructor you need to get rid of:
Concrete(const Concrete& c) = delete;
and you'll have to cast your c1 and c2
Concrete c1(Base::getHeadInstance());
Concrete c2((Base&)c1);
Concrete c3((Base&)c2);
Your other option is to template the constructor:
template<typename T>
Concrete(T& f): fwd(f) {}
and then your original code would work (Yay!).
Concrete c1(Base::getHeadInstance());
Concrete c2(c1);
Concrete c3(c2);

You just need to provide you own copy constructor that does what you want. Adding
Concrete(Concrete& c): fwd(c) {}
Will then make
Concrete c1(Base::getHeadInstance());
Concrete c2(c1);
Concrete c3(c2);
have c1.fwd == Base::getHeadInstance(), c2.fwd == c1, and c3.fwd == c2

Another possible solution is to avoid using references; even if I admit it is not isomorphic.
class Concrete : public Base {
public:
explicit Concrete(Base* f) : fwd(*f) {
// possibly you want to assert precondition? assert(f)?
}
private:
Base& fwd; // I would prefer Base* here...
};
In that way, you don't risk to call the implicit copy constructor of Concrete; without override o delete anything.
Concrete c1(&Base::getHeadInstance());
Concrete c2(&c1);
Concrete c3(&c2);

Related

Check for template class equality through base class pointer

Is it possible to check, through a base class pointer, whether different derived template classes are specialization of the same template class?
This is achievable through introducing an intermediate non-template base-class. However, i would like to know whether this pattern is avoidable when the sole purpose of this intermediate class is for identification:
class A{}
class B_base : public A{}
template<T>
class B : public B_base {}
// There may be other derived classes of A
template<T>
class C: public A{}
void main() {
// ... some vector of pointers to A derived objects
std::vector<A*> v;
for(auto& i : v){
// Check whether i is any specialization of B through a
// dynamic_cast to the intermediate class
if(dynamic_cast<B_base*>()){
// This is a B_base object,
}
}
}
Ideally, i would like something like this, to avoid the intermediate class.
class A{}
template<T>
class B : public A{}
// There may be other derived classes of A
template<T>
class C: public A{}
void main() {
// ... some vector of pointers to A derived objects
std::vector<A*> v;
for(auto& i : v){
// Check whether i is any specialization of B
if(templateTypeId(i) == templateTypeId(B*)){
// This is a B object with some unknown specialization
}
}
}
Different specializations of a template are entirely unrelated types for most purposes. Template argument deduction can deduce a template and its arguments from such a type, but that happens entirely at compile time. There is no guaranteed run time information that can tell whether a class is a specialization of a given template, whether two classes are specializations of the same template, etc.
So you would need to set up a way to test this yourself, but your intermediate class method is not the only option. The most straightforward way would be to put a way to test it into the base A class:
class A {
public:
virtual ~A() = default;
virtual bool is_B() const noexcept { return false; }
};
template <class T>
class B : public A {
public:
bool is_B() const noexcept override { return true; }
};
Though this gets a bit ugly if there are several different B-like categories to test for, and doesn't work if it should be possible to extend A with new subtypes, and then test for those subtypes in a similar way.
Another idea would be to associate the type check with an object address:
struct type_tag {
constexpr type_tag() = default;
type_tag(const type_tag&) = delete;
type_tag& operator=(const type_tag&) = delete;
};
class A {
public:
virtual ~A() = default;
virtual bool matches_type(const type_tag&) const
{ return false; }
};
inline constexpr type_tag B_tag{};
template <class T>
class B {
public:
bool matches_type(const type_tag& tag) const override
{ return &tag == &B_tag; }
};
This pattern also allows for categories of subtypes that don't come from just one template. It also doesn't prevent a new class from "lying" about its own type, if that might be a concern, but it might be best not to try to prevent that, but let any implemented derived class be responsible for its own behavior, which might mean it wants to act "almost exactly like" some other type.
May be a better design is to add required virtual functions to interface A, so that you can invoke them directly on A* without guessing the derived class. The latter is an anti-pattern because it defeats the purpose of polymorphism: the idea that a piece of code can work with object of different classes without knowing their exact type. You may as well put objects of different types into different containers and not use ploymorphism based on virtual functions at all.

Is it possible to switch to a different base class constructor at runtime?

Suppose I'm writing Derived and have to inherit from Base, which I don't control and has two separate constructors and a deleted copy and move constructors:
struct Base {
Base(int i);
Base(const char *sz);
Base(const Base&) = delete;
Base(const Base&&) = delete;
};
struct Derived {
Derived(bool init_with_string);
};
Now, depending on the value of another_param I have to initialize my base class using either a constructor or the other; if C++ was a bit less strict it would be something like:
Derived::Derived(bool init_with_string) {
if(init_with_string) {
Base::Base("forty-two");
} else {
Base::Base(42);
}
}
(this would also be useful for all the cases where it's cumbersome to calculate values to pass to base class constructors/fields initializers in straight expressions, but I'm digressing)
Unfortunately, even if I don't see particular codegen or object-model obstacles to this kind of thing, this isn't valid C++, and I cannot think of easy workaround.
Is there some way around this that I'm not aware of?
A static function will work fine here
struct Base {
Base(int i);
Base(const char *sz);
Base(const Base&) = delete;
Base(const Base&&) = delete;
};
struct Derived : Base {
using Base::Base;
static Derived construct(bool with_string) {
if(with_string) return { "forty-two" };
return { 42 };
}
};
Notice that this does not require a move, nor a copy constructor. If you want to have this as a local, you need to bind it to a reference in order to avoid moving it
auto &&w = Derived::construct(true);
auto &&wo = Derived::construct(false);
Not ideal but I have used this technique when nothing better suggested itself, when the initialization of an object had to occur inside a code block:
// (Same base as your code)
#include <memory>
struct Derived : public Base {
using Base::Base;
};
int main(int argc, char **argv)
{
std::unique_ptr<Derived> pd;
if ( argc == 2 )
{
pd = std::make_unique<Derived>(42);
}
else
{
pd = std::make_unique<Derived>("forty-two");
}
Derived &d = *pd;
// use d, don't manually reset pd
}
It's not really the answer you're looking for, but if you can get to a point where the decision is exposed to the code calling the constructor, you can use a tag-dispatch template constructor with a generic lambda for constexpr-if (bingo!), as follows:
#include <type_traits>
#include <memory>
struct Base {
Base(int) {};
Base(const char *) {};
Base(const Base&) = delete;
Base(const Base&&) = delete;
};
struct Derived : Base{
static std::unique_ptr<Derived> make_unique(bool init_with_string);
private:
template<typename init_with_string_t>
Derived(init_with_string_t);
};
template<typename init_with_string_t>
Derived::Derived(init_with_string_t) : Base([]{if constexpr(init_with_string_t::value) return "forty-two"; else return 42;}())
{
}
std::unique_ptr<Derived> Derived::make_unique(bool init_with_string)
{
if (init_with_string)
return std::unique_ptr<Derived>(new Derived(std::true_type{}));
else
return std::unique_ptr<Derived>(new Derived(std::true_type{}));
}
int main()
{
auto d1 = Derived::make_unique(true);
auto d2 = Derived::make_unique(false);
}
Live demo on wandbox
That's a C++17-heavy feature list, so clang 3.9 or gcc 7. As I did here, you can wrap up the tag-dispatch call with a factory, and if you make that a static member of the class, you can put the logic that selects whether to initialise with a string or a value in a private static class method, or inline in the factory method as you prefer.
Some less-than-pleasant issues I had to work around to get this working:
The type-dispatch is needed because even through we could have Derived's constructor be:
template<bool init_with_string>
Derived::Derived() : Base([]{if constexpr(init_with_string) return "forty-two"; else return 42;}())
{
}
there's actually no way to explicitly specify template parameters to a constructor, and template deduction cannot deduce non-type template parameters. (If you have access to a constexpr value in scope, you could probably do something like template<bool init_with_string = constexpr_bool_method()> but if you could do that, you could put that straight in the lambda.
The if constexpr lambda idea came from an answer to Equivalent ternary operator for constexpr if?, which would have been nicer.
Sadly, we can't use std::make_unique in a factory method to access private constructors, because friendship isn't transitive.
Edit: The following approach is quite close to what you are after, using placement new:
struct Derived3 : Base
{
Derived3::Derived3(bool init_with_string) : Base(42)
{
if(init_with_string)
{
// in case of any resources would have been allocated:
this->~Derived3();
new(this) Derived3("forty-two");
}
}
private:
using Base::Base;
};
First I construct a Base object with one of the two types. If the type condition does not match, I need to destroy it again calling the destructor explicitly to avoid undefined behaviour (and to prevent leaks in case that Base allocated memory already). Afterwards, we can reconstruct the class using the other constructor. Well, and this is the drawback of this approach, we potentially allocate some memory in vain, just to release it afterwards again and then re-allocate it! At least, we create an object in vain in some of the cases.
So no non-plus-ultra solution, so I'll leave my previous approaches:
Currently offering two approaches, both not really what you are after, but for now, I did not get closer...
Well, the obvious and easy solution:
struct Derived1 : Base
{
static Derived1* instance(bool init_with_string)
{
return init_with_string ? new Derived1("forty-two") : new Derived1(42);
}
private: // or even not, then you can construct your derived classes directly...
using Base::Base;
};
int main(int argc, char* argv[])
{
Derived1* d1 = Derived1::instance(false);
}
Template variant:
struct Derived2 : Base
{
private:
using Base::Base;
template <bool>
friend struct Derived2Maker;
};
template <bool InitWithString>
struct Derived2Maker : Derived2
{
Derived2Maker() : Derived2(42) { }
};
template <>
struct Derived2Maker<true> : Derived2
{
Derived2Maker() : Derived2("forty-two") { }
};
int main(int argc, char* argv[])
{
Derived2* d2 = new Derived2Maker<false>();
}
Drawback: boolean parameter must be known at compile time...
Honestly you should just respect the implementation of Base and let Derived have two constructors.
class Derived : Base {
Derived(int i) : Base(i) {}
Derived(const char *s) : Base(s) {}
}
Then as Johannes Schaub remarked it's actually possible to have an external make_derived() using initializer lists even without copy constructors.

Virtual Function During Construction Workaround

I've got a base class that has a virtual function. I want to call that class during the construction because I want the function called for each of the derived classes. I know I can't call a virtual function during construction, but I can't think of an elegant (i.e., avoid repeating code) solution.
What are some work arounds to calling a virtual function during construction?
The reason I want to avoid this is because I don't want to have to create constructors that just call the base class.
class A {
public:
A() {
read();
}
// This never needs to be called
virtual void read() = 0;
}
class B:A {
public:
B():A() { };
read() { /*Do something special for B here.*/ }
}
class C:A {
public:
C():A() { };
read() { /*Do something special for C here.*/ }
}
PS: The Python way of doing this is simply to raise NotImplementedError in A::read(). I'm returning to C++ and I'm more rusty than I thought.
The FAQ perspective.
This is a Frequently Asked Question.
See the C++ FAQ item titled “Okay, but is there a way to simulate that behavior as if dynamic binding worked on the this object within my base class's constructor?”.
It’s very often a good idea to check the FAQ (and generally, googling or altavista’ing) before asking.
The question as “Derived class specific base initialization”.
To be clear, while the literal question above is
“What are some work arounds to calling a virtual function during construction?”
it is evident that what’s meant is
“How can a base class B be designed so that each derived class can specify part of what goes on during B construction?”
A major example is where C style GUI functionality is wrapped by C++ classes. Then a general Widget constructor might need to instantiate an API-level widget which, depending on the most derived class, should be a button widget or a listbox widget or whatever. So the most derived class must somehow influence what goes on up in Widget’s constructor.
In other words, we’re talking about derived class specific base construction.
Marshall Cline called that “Dynamic Binding During Construction”, and it’s problematic in C++ because in C++ the dynamic type of an object during class T construction and destruction, is T. This helps with type safety, in that a virtual member function is not called on a derived class sub-object before that sub-object has been initialized, or its initialization has started. But a major cost is that DBDI (apparently) can’t be done in a way that is both simple and safe.
Where the derived class specific init can be performed.
In the question the derived class specific action is called read. Here I call it derived_action. There are 3 main possibilities for where the derived_action is invoked:
Invoked by instantiation code, called two-phase construction.
This essentially implies the possibility of having a mostly unusuable not fully initialized object at hand, a zombie object. However, with C++11 move semantics that has become more common and accepted (and anyway it can be mitigated to some extent by using factories). A main problem is that during the second phase of construction the ordinary C++ protection against virtual calls on uninitialized sub-objects, due to dynamic type changes during construction, is not present.
Invoked by Derived constructor.
For example, derived_action can be invoked as an argument expression for the Base constructor. A not totally uncommon technique is to use a class template to generate most derived classes that e.g. supply calls of derived_action.
Invoked by Base constructor.
This implies that knowledge of derived_action must be passed up to the constructor, dynamically or statically. A nice way is to use a defaulted constructor argument. This leads to the notion of a parallel class hierarchy, a hierarchy of derived class actions.
This list is in order of increasing sophistication and type safety, and also, to the best of my knowledge, reflects the historical use of the various techniques.
E.g. in Microsoft’s MFC and Borland’s ObjectWindows GUI early 1990’ libraries two-phase construction was common, and that kind of design is now, as of 2014, regarded as very ungood.
This is the factory method approach, putting the factory into the base class:
class A {
public:
virtual void read() = 0;
template<class X> static X* create() {X* r = new X;X->read();return X;}
virtual A* clone() const = 0;
};
class B : public A {
B():A() { };
friend class A;
public:
void read() { /*Do something special for B here.*/ }
B* clone() const {return new B(*this);}
};
class C : public A {
C():A() { };
friend class A;
public:
void read() { /*Do something special for C here.*/ }
C* clone() const {return new C(*this);}
};
Added a clone-method with covariant return type as a bonus.
Using CRTP:
class A {
public:
// This never needs to be called
virtual void read() = 0;
virtual A* clone() const = 0;
};
template<class D, class B> struct CRTP : B {
D* clone() {return new D(*this);}
static D* create() {return new D();}
};
class B : public CRTP<B, A> {
B() { };
public:
void read() { /*Do something special for B here.*/ }
};
class C : public CRTP<C, A> {
C() { };
public:
void read() { /*Do something special for C here.*/ }
};
One way to achieve this, would be simply to delegate it to another class (that is perhaps a friend) and can be sure to be called when fully constructed.
class A
{
friend class C;
private:
C& _c; // this is the actual class!
public:
A(C& c) : _c(c) { };
virtual ~A() { };
virtual void read() = 0;
};
class B : public A
{
public:
B(C& c) : A(c) { };
virtual ~B() { };
virtual void read() {
// actual implementation
};
};
class C
{
private:
std::unique_ptr<A> _a;
public:
C() : _a(new B(*this)) { // looks dangerous? not at this point...
_a->read(); // safe now
};
};
In this example, I just create a B, but how you do that can depend on what you want to achieve and use templates on C if necessary, e.g:
template<typename VIRTUAL>
class C
{
private:
using Ptr = std::unique_ptr<VIRTUAL>;
Ptr _ptr;
public:
C() : _ptr(new VIRTUAL(*this)) {
_ptr->read();
};
}; // eo class C
The workaround is to call the virtual function after construction. You can then couple the two operations (construction + virtual call) in factory function. Here is the basic idea:
class FactoryA
{
public:
A *MakeA() const
{
A *ptr = CreateA();
ptr->read();
return ptr;
}
virtual ~FactoryA() {}
private:
virtual A *CreateA() const = 0;
};
class FactoryB : public FactoryA
{
private:
virtual A *CreateA() const { return new B; }
};
// client code:
void f(FactoryA &factory)
{
A *ptr = factory.MakeA();
}
As mentioned by Benjamin Bannier, you can use CRTP (a template which defines the actual read() function.) One problem with that method is that templates have to always be written inline. That can at times be problematic, especially if you are to write really large functions.
Another way is to pass a function pointer to the constructor. Although, in a way, it is similar to calling the function in your constructor, it forces you to pass a pointer (although in C++ you could always pass nullptr.)
class A
{
public:
A(func_t f)
{
// if(!f) throw ...;
(*f)();
}
};
class B : A
{
public:
B() : A(read) {}
void read() { ... }
};
Obviously, you have the "can't call other virtual functions" problem within the read() function and any function it calls. Plus, variable members of B are NOT yet initialized. That is probably a much worst problem in this case...
For that reason, writing it this way is safer:
B() : A()
{
read();
}
However, in cases like that, that may be the time when you an some for of init() function. That init() function can be implemented in A() (if you make it accessible: i.e. use public A when deriving) and that function can call all the virtual functions as expected:
class A
{
public:
void init()
{
read();
}
};
class B : public A
{
public:
...
};
I know a lot of people say that an init() function is evil because people who create a B object now need to know to call it... but there isn't much else you can do. That being said, you could have a form of factory, and that factory can do the init() call as required.
class B : public A
{
public:
static B *create() { B *b(new B); b->init(); return b; }
private:
B() { ... } // prevent creation without calling create()
};

How to invoke parameterised constructor in PIMPL design pattern?

How to use PIMPL design for parameterized constructor?
/* ProcessImpl.h */
class ProcessImpl {
public :ProcessImpl();
ProcessImpl(ProcessID thirdParty_pid);
~ProcessImpl();
}
/* Process.h */
class Process {
public:virtual ~Process () {};
Process();
Process(ProcessID thirdParty_pid);
protected:
void createImpl();
private:
ProcessImpl * _impl;
}
/* Process.cpp */
Process::Process():_impl(NULL) {
}
Process::Process(ProcessID thirdParty_pid) {
createImpl();
_impl->ProcessImpl(ldframework::ProcessID thirdParty_pid);
}
void Process::createImpl(){
if(this->_impl == NULL) {
this->_impl = new ProcessImpl();
}
}
When I compile this I am getting error:
Process.cpp: error: invalid use of class ProcessImpl
This is the line throwing error _impl->ProcessImpl(ldframework::ProcessID thirdParty_pid)
Please help
Since your code is not valid C++ I won't jump into conclusions about your actual implementation, so I will start from the beginning:
If a class has a parametrized constructor, the parameters are needed to directly or indirectly initialize class members and base classes. Since a pimpl'd class has no data members of its own (except the pimpl), constructor parameters are needed only for the initialization of the implementation class.
There are two extremes of the pimpl idiom implementation:
All the logic goes into the implementation class, and the outer class is only a dumb fassade, forwarding any calls to the pimpl.
The logic remains in the outer class, the pimpl is only a dumb bundle of data.
Of course, in practice, anything in between is possible.
In case 1, the outer class' constructor signatures should be the same as the signature of the implementation class' constructors and just pass any arguments to the pimpl constructors:
Foo.h
class Foo {
struct FooImpl;
std::unique_ptr<FooImpl> pImpl;
public:
~Foo();
Foo(A const& a);
Foo(B b, C* c, D& d);
};
Foo.cpp
struct Foo::FooImpl {
FooImpl(A const& a);
FooImpl(B b, C* c, D& d);
/* Logic goes here */
};
Foo::~Foo() {} //defined here for correct deletion of the unique_ptr
Foo::Foo(A const& a)
: pImpl(std::make_unique<FooImpl>(a))
{}
Foo::Foo(B b, C* c, D& d)
: pImpl(std::make_unique<FooImpl>(std::move(b), c, d))
{}
Together:
Use the same constructor signatures for the class and the pimpl-class, each class constructor just calls the corresponding pimpl-constructor
Parameters taken by reference or pointer are passed as-is to the pimpl constructor
Parameters taken by value are moved to the pimpl constructor (forwarding)
That is the simplest possible solutution where the constuctor logic is entirely implemented inside the implementation class.
In the other case, where the pimpl class is only a bundle of data, you will have the logic inside the outer class` constructor, like this:
struct Foo::FooImpl {
FooImpl(A const& a, B b, E e, F f);
A a;
};
Foo::Foo(B b, C* c, D& d)
: pImpl(std::make_unique<FooImpl>(A(), std::move(b), calcE(c,d), getSomeF())
{
pImpl->a = someValueForA();
}
You see, the strategy to implement the constructors depends on your strategy to implement the pimpl idiom alltogether. Just make sure you are somewhat consistent in either delegating the logic to the pimpl class or leaving it in the main class.
Just construct the pimpl in the constructor.
Note that you should also implement a copy constructor and assignment operator as copying the object will result in undefined behaviour when both copies are destructed.
Ideally the pimpl should always be valid to avoid checking if it is valid all the time, but going by your code, you could perhaps have the following:
class Process {
public:
virtual ~Process () {
};
Process() {
// Ideally the impl_ pointer should be intialized to avoid
// having to check it in every function that uses it..
}
Process(ProcessID pid) {
impl_.reset(new ProcessImpl(pid));
}
Process(Process const& rhs) {
if (rhs.impl_.get()) {
impl_.reset(new ProcessImpl(*rhs.impl_));
}
}
Process& operator=(Process const& rhs) {
if (this != &rhs) {
if (rhs.impl_.get()) {
impl_.reset(new ProcessImpl(*rhs.impl_));
}
else {
impl_.reset();
}
}
return *this;
}
private:
std::unique_ptr<ProcessImpl> impl_;
};

C++ casting to derived and parent structs

I was wondering how to do something in C++. I want to be able to create an instance of this struct
struct ComplexInstruction : simple_instr
{
bool isHead;
bool isTail;
};
that copies all the data from the simple_instr instance. So essentially, I want to do something like this
ComplexInstruction cInstr = instr; // <- instance of simple_instr
and have cInstr have a copy of all the data in instr without having to copy over every field (since there's alot of them). I'm not sure how do this, and I don't think simple casting will work. Additionally, is it possible to do the reverse? I.e. have an instance of ComplexInstruction and turn it into an instance of simple_instr. I assume this can be done using casting, but I don;t have alot of experience with c++
Thanks in advance
Create a consctructor in the derived class to initialize from a base class.
class Base
{
int x;
public:
Base(int a) : x(a){}
};
class Derived : public Base
{
public:
Derived(const Base & B) : Base(B){}
};
Note that if you have a derived object of Base, you actually have a base object and you can safely use the base copy ctor like so.
Derived d;
Base b(d);//the parts of Base that are in Derived are now copied from d to b.
//Rest is ignored.
If you want to be more verbose, you write an operator= in your derived class like
void operator=(const Base & b)
{
Base::operator=(b);
//don't forget to initialize the rest of the derived members after this, though.
}
It all depends on what you want to do, really. The important thing is: be explicit. Don't leave uninitialized members of your class.
You need to provide a constructor that takes an argument that is convertible to const simple_instr&:
struct simple_instr {
int i;
simple_instr(): i(0) { }
explicit simple_instr(int i): i(i) { }
};
struct ComplexInstruction: simple_instr {
explicit ComplexInstruction(const simple_instr& simple):
simple_instr(simple), isHead(false), isTail(false) { }
bool isHead;
bool isTail;
};
int main() {
simple_instr instr;
ComplexInstruction cInstr(instr);
}
Here I chose an explicit constructor, but depending on the semantics, an implicit one could also be appropriate. Only if the constructor is implicit, the =-style initialization works without casting.
Edit: This is not the best way to accomplish this, please look at the other answers.
This will do what you are looking for.
struct ComplexInstruction : simple_instr
{
ComplexInstruction(const simple_instr &simple)
{
*((simple_instr*)this) = simple;
}
bool isHead;
bool isTail;
};
Then ComplexInstruciton complex = simple; will call the conversion constructor. ComplexInstruction's copy construct casts this to its base class and the = will call simple_instr's copy constructor, which by default is a bitwise copy.