class inheritance call a different constructor - c++

hei i have a c++03 class with a simple constructor that take an integer. And a derived class with serialization methods that should take a filename as a constructor, load the integer from it, and then call the first constructor.
class A {
public:
A(int foo);
}
and a derived class:
class XmlableA : public A {
public:
XmlableA(int foo);
XmlableA(string xmlfilename) {
//load foo from xml
// call A::A(foo)
}
}
i tried some different solution but every time i get
no matching function for call to ‘A::A()’

Almost all answers are same, so I would suggest a different solution, which I would prefer personally.
Define a static member function Create as:
class XmlableA : public A {
public:
XmlableA(int foo);
//static member function
static XmlableA Create(string const & xmlfilename)
{
//load foo from xml
int foo = /*load from file*/;
return XmlableA(foo);
}
};
Usage:
XmlableA xmlable = XmlableA::Create(xmlFile);

Initialize it, like so:
XmlableA(int foo) : A(foo) {}
You may also consider:
private:
static int LoadXML(const string& xmlfilename) {
int ret = ...; << load here
return ret;
}
public:
XmlableA(string xmlfilename) : A(LoadXML(xmlfilename)) {
}

In C++ the Base class is constructed BEFORE the Child class, so you will not be able to do this. You could make a Factory that takes a filename and creates an object based on what is in that file.
Example:
class XmltableAFactory {
public:
static XmltableAFactory build(string xmlfilename) {
// read int foo from xmlfilename
return XmltableAFactory(foo);
}
};
And then call it like so:
XmltableA myObj = XmltableAFactory::build(filename);
There are a few things to note.
This means that you will not need the string xmlfilename cosntructor in the XmltableA class because as discussed above, you cannot know foo before the base class's constructor is called.
You can either choose to return from the factory by value or by pointer. The compiler might optimize the return by value because you are creating the object and returning it on the same line. However, return by pointer is usually known to be faster, but you'll have to create a new object and then make sure to delete it when you're done with it.
If you don't want to muck about with memory, take a look at boost's auto_ptr and shared_ptr.

If you want to do something before the call to A::A(int), you end up having to hack, something like
int XmlableA::f(string filename) { /* load foo from xml */; return foo; }
XmlableA(string xmlfilename) : A(f(filename)) {}

OK, so the first one is easy:
XmlableA::XmlableA(int foo) : A(foo)
{
}
The second one requires doing something like
XmlableA(string xmlfilename) : A(fooFromXML(xmlfilename))
{
}
which we can implement as
class XmlableA : public A
{
static int fooFromXML(string filename);
public:
// ...
Note that fooFromXML, which loads the XML file and returns the integer you need, must be static, because when we call it we don't yet have an XmlableA instance to invoke it on.
For multiple arguments (and as a general design), the factory is probably best: if you're wedded to the constructor model and don't care about efficiency, you can do:
class XmlableA : public A
{
static int intFromXML(char const *varname, string const &filename);
public:
XmlableA(string const &xmlfilename)
: A(intFromXML("foo", xmlfilename), intFromXML("bar", xmlfilename))
{
}
if you're concerned about parsing the XML file repeatedly, and don't care about re-entrancy, you can "memoize" xFromXML by having it cache state in a static member.

If your class A does not have a default constructor you have to explicitly call a constructor in the initialization list of your derived class. XmlableA(string fn) : A(readIntegerFromFile(fn)) {}.
However, you should think about "outsourcing" the serialization into a separate class. E.g. what would happen if you have an object of type A and now you want to serialize it? You couldn't because you can only serialize a XmlableA. Furthermore, what would happen if your client decides that he no longer wants a XML serialization but Yaml or some proprietary format? You would have to change all your code.

Related

Proper design setup for derived classes with common attributes but different values

So I can think of a few ways to do this but I feel like I am just retyping the same thing with each new subclass. Is there a design pattern where I can set up the full structure for my subclasses in a way where I reduce the amount of code needed for implementation (and also enforce proper implementation if possible?)
This seems simple but the ideas I've had don't work, and the best I've found is to either hard code in the parameters when calling the constructor or to set up new constants within each child class then use those.
What I currently have is something like this:
"parent.hpp"
class Parent {
private:
std::string name;
int someValue;
protected:
Parent(std::string name, int someValue); // NOTE: There will be 7 parameters/attributes that need initial base values
void setName(std::string name) { this->name = name; }
void setSomeValue(int someValue) { this->someValue = someValue; }
public:
std::string getName() { return this->name; }
int getSomeValue() { return this->someValue; }
};
"parent.cpp"
Parent::Parent(std::string name, int someValue) {
setName(name);
setSomeValue(someValue);
}
"child.hpp"
class Child : public Parent {
public:
Child();
};
"child.cpp - option 1"
static const std::string DEFAULT_NAME = "Jon";
static const int DEFAULT_SOME_VALUE = 100;
Child::Child() : Parent(DEFAULT_NAME, DEFAULT_SOME_VALUE) {
// other stuff if needed
}
"child.cpp - option 2"
Child::Child() : Parent("Jon", 100) {
// other stuff if needed
}
There will be virtual methods and such I'll add later, but for now I just want to know of the right design pattern for having (potentially) many subclasses. There are also more parameters that will be in common which are all int values. It would seem unclear to me to have the constructors be Child::Child("string", 1, 2, 3, 4, 5, 6) albeit it would be easier to implement new subclasses.
On the other hand if I am just retyping the boiler plate constants for the base values in each subclass, the constructors will be more descriptive, but there would be a lot of code reuse.
It would seem to me what I would want to do is have virtual protected constants in the Parent class which the Child classes would need to define, then call those from the constructors, but that is not allowed. Is one of the two options a better one? Is there a better "long-term" setup for this?
I looked through all of the Similar Questions and the closest I found was this: Proper way to make base class setup parent class. Though I'm not really sure if that idea would fix my issue or make anything clearer.
Another idea I had was to call pure virtual methods from the default constructor, but as I learned that is also not allowed.
I would use another object to hold the state like Ami, although I would have done it for a different reason. Since the state is a separate class, you can fully construct it before the actual Parent and Child are constructed, and it can have its own hierarcy.
header
class Parent {
protected:
struct ParentState {
std::string name;
int someValue;
};
Parent(ParentState);
void setName(std::string name) { data.name = name; }
void setSomeValue(int someValue) { data.someValue = someValue; }
public:
std::string getName() { return data.name; }
int getSomeValue() { return data.someValue; }
private:
ParentState data;
};
class Child : public Parent {
struct ChildDefaults : public Parent::ParentState {
ChildDefaults();
};
public:
Child();
};
implementation
Parent::Parent(ParentState init) {
// since you have setters, they should be used
// instead of just data=init;
setName(init.name);
setSomeValue(init.someValue);
}
Child::ChildDefaults::ChildDefaults(){
name = "Jon";
someValue = 100;
}
Child::Child() : Parent(ChildDefaults()){
// other stuff if needed
}
If you put the ParentState and ChildDefault classes in a separate file, you can use that file to put all the defaults in one place where you can easily look them up or change them. They also might be prettier if they are not hidden inside the classes, forcing the extra scope syntax.
addendum:
To put the whole default settings heirarchy together in its own header, just move them all to one header. Be sure to do an include guard to avoid multiply defining the constructors.
#ifndef THE_DEFAULTS_H
#define THE_DEFAULTS_H
struct ParentState {
std::string name;
int someValue;
};
struct ChildDefaults : public Parent::ParentState {
ChildDefaults() {
name = "Jon";
someValue = 100;
}
};
// more default settings for other classes
#endif
Perhaps you could combine here two ideas:
Avoiding a large number of args passed to a function in general (including a ctor).
Method chaining.
(The first one is more fundamental here, and the second one is less essintial, and is here just for improved readability.)
In more detail:
Having any function, a ctor of a base class in particular, taking 7 parameters, seems very verbose & fragile. Suppose you realize that you needed to add another parameter. Would you now have to go over all the derived classes? That's problematic.
So let's start with something like:
class Parent
{
protected:
explicit Parent(const ParentParams &params);
};
And ParentParams looks something like this:
class ParentParams
{
public:
// Initialize with default stuff.
ParentParams();
// Changing only the foo aspect (via method chaining).
ParentParams &setFoo(Foo foo_val)
{
m_foo = foo_val;
return *this;
}
// Changing only the bar aspect (via method chaining).
ParentParams &setBar(Bar bar_val)
{
m_bar = bar_val;
return *this;
}
// Many more - you mentioned at least 7.
....
};
Now a child could look something like this:
// A child that happens to have the property that it changes foo and bar aspects.
class FooBarChangingChild :
public Parent
{
public:
FooBarChangingChild();
};
And in its implementation:
// Static cpp function just creating the params.
static ParentParams makeParams()
{
// Note the clarity of which options are being changed.
return ParentParams()
.setFoo(someFooVal)
.setBar(someBarVal);
}
FooBarChangingChild::FooBarChangingChild() :
Parent(makeParams())
{
}

Call virtual method immediately after construction

I need to call a virtual method for all classes derived from a given base base class right after the construction of the derived object. But doing so in the base class constructor will result in a pure virtual method call
Here is a simplified example:
struct Loader {
int get(int index) { return 0; }
};
struct Base{
Base() {
Loader l;
load( l ); // <-- pure virtual call!
}
virtual void load( Loader & ) = 0;
};
struct Derived: public Base {
int value;
void load( Loader &l ) {
value = Loader.get(0);
}
};
I can call load at the Derived constructor, but Derived could not know how to create a Loader. Any ideas/workarounds?
The problem is that base class construction occurs before the derived class is fully constructed. You should either call "load" from the derived class, initialise throguh a different virtual member function or create a helper function to do this:
Base* CreateDerived()
{
Base* pRet = new Derived;
pRet->Load();
return pRet;
}
The C++ FAQ calls this problem DBDI, Dynamic Binding During Construction. Mainly, the problem is to avoid the Evil two-phase construction advocated in other answers here. It's sort of "my" FAQ item -- I convinced Marshall to add it.
However, Marshall's take it on it is very general (which is good for a FAQ), while I was more concerned with the particular design/coding pattern.
So, instead of sending you to the FAQ I send you to my own blog, the article "How to avoid post-construction by using Parts Factories", which links to the relevant FAQ item, but discusses in depth the pattern.
You can just skip the first two paragraphs...
I sort of rambled there. :-)
Cheers & hth.,
Use the PIMPL pattern:
template<typename T>
class Pimpl
{
public:
Pimpl()
{
// At this point the object you have created is fully constructed.
// So now you can call the virtual method on it.
object.load();
}
T* operator->()
{
// Use the pointer notation to get access to your object
// and its members.
return &object;
}
private:
T object; // Not technically a pointer
// But otherwise the pattern is the same.
// Modify to your needs.
};
int main()
{
Pimpl<Derived> x;
x->doStuff();
}
Can't you add a method getLoader() in your Base class so that DerivedClass constructor can call it on this to get a Loader ?
As DerivedClass constructor will be called after Base class constructor, that should work fine.
Its hard to give advice unless you tell us what you are trying to accomplish, rather than how. I find that its usually better to construct such objects from a factory, which will load the required data before-hand, and then pass the data into the constructor of the object.
Many known frameworks (like MFC) do this: They make a (virtual) member-function Init() or Create() and do the initialization there and then mandate in the documentation that the user call it. I know you won't like this idea, but you just can't call a virtual method from a constructor and expect it to behave polymorphically, regardless of the methods pureness...
This may come a little late after other answers, but I'll still give it a try.
You can implement this safely, and without changing derived classes. However, you will need to change use of all these classes, which might be far worse, depending on your scenario. If you are still designing, then this might be viable alternative.
Basically, you can apply the curiously recurring template pattern and inject the initialization code after the constructor gets invoked. Furthermore, if you do it as I've written it below, you can even protect load from being called twice.
struct Loader {
int get(int index) { return 0; }
};
struct Base {
virtual ~Base() {} // Note: don't forget this.
protected:
virtual void load( Loader & ) = 0;
};
struct Derived : public Base {
int value;
protected:
void load( Loader &l ) {
value = l.get(0);
}
};
template<typename T>
class Loaded : public T
{
public:
Loaded () {
Loader l; T::load(l);
}
};
int main ( int, char ** )
{
Loaded<Derived> derived;
}
Frankly, though, I would consider an alternate design if you can. Move the code from load to your constructors and provide the loader as an a reference argument defaulting as follows:
struct Derived : public Base {
Derived ( Loader& loader = Loader() ) { ... }
};
That way, you completely avoid the problem.
Summary: your choices are the following:
If you are not limited by external constraints and don't have an extensive code base depending on this, change your design for something safer.
If you want to keep load the way it is and not change your classes too much but are willing to pay the price of changing all instantiations, apply CRTP as proposed above.
If you insist on being mostly backward compatible with existing client code, you will have to change you classes to use a PIMPL as others have suggested or live with the existing problem.
There are many ways to correct this, here is 1 suggestion fitting within your provided framework
struct Loader {
int get(int index) { return 0; }
};
struct Base{
Base() {
}
Loader & getLoader( );
private:
Loader l;
};
struct Derived: public Base {
int value;
Derived( ) {
value = getLoader().get(0);
}
};

Data structure that can hold multiple types of data

Like the title says, I'm looking for some kind of data structure which will allow me to store any type of class into it that I need at the time. For example:
Foo *foo = new Foo();
Bar *bar = new Bar();
someContainer.push_back( foo );
someContainer.push_back( bar );
someContainer.access( 0 )->doFooStuff();
someContainer.access( 1 )->doBarStuff();
Ideally, as I showed there, it would also allow me to access the contents and use their functions/etc.
I want one of these as I am attempting to create an "invisible" memory management system that just requires a class to inherit my memory manager class, and everything will work automagically.
Here is an example of what I want the code to look like:
template< class T >
class MemoryManaged
{
MemoryManaged()
{
container.push_back( this );
}
void *operator new()
{
// new would probably be overloaded for reference counting etc.
}
void operator delete( void *object )
{
// delete would most definitely overloaded
}
T &operator=( T &other )
{
// = overloaded for reference counting and pointer management
}
static SomeContainer container;
}
class SomeClass : public MemoryManaged< SomeClass >
{
// some kind of stuff for the class to work
};
class AnotherClass : public MemoryManaged< AnotherClass >
{
// more stuff!
};
I hope that my code helps make clear what exactly it is I want to do. If someone knows some kind of already-built data structure that would allow me to do this, that would be awesome. Otherwise, I am currently working on building some kind of shambling zombie of a linked list class that uses templated nodes in order to link any type of class to any other type of class. I still have no idea how I'd get it to work yet, and I would love to be spared the blood, sweat, and tears (and hair) it would take to figure out how to make it work.
Have a common base class for all of your multiple types. Have the data structure hold onto pointers of your base class's type.
Take a look at boost::any and boost::variant.
Would some hybrid of template specialization and double-dispatch help? Something like this:
class IContainable;
class Operation
{
public:
template<class ElementType> void Process(ElementType* pEl) {
// default is an unrecognized type, so do nothing
}
};
class IContainable
{
public:
virtual void OperateOn(Operation* pOperation) = 0;
};
class Foo : public IContainable
{
public:
int GetFooCount() { return 1; }
virtual void OperateOn(Operation* pOperation);
};
// specialization of the operation for Foo's
template <> void Operation::Process<Foo>(Foo* pFoo)
{
std::cout << pFoo->GetFooCount() << std::endl;
}
void Foo::OperateOn(Operation* pOperation)
{
pOperation->Process(this);
}
int main()
{
typedef std::vector<IContainable*> ElementVector;
ElementVector elements;
// configure elements;
Operation oper;
for(ElementVector::iterator it = elements.begin();
it != elements.end(); it++)
{
(*it)->OperateOn(&oper);
}
}
If the list of types in the container isn't known at compile time of the operations of the elements on the container, or they are distributed across modules that are not compiled together, then you could instead use dynamic_cast. You'd define a "IFooHandler" class witha pure virtual method called "HandleFoo" that takes a foo pointer. You'd make Operation::Process virtual and have your operation class derive from both Operation and IFooHandler and implement the operation in HandleFoo(). Your Foo::OperateOn method would dynamic_cast(pOperation) and if the result was non-null, it would call HandleFoo() on the IFooHandler pointer you get from the dynamic cast. Otherwise you'd call the generic Operation::Process and it would have some non-type-specific behavior.
Using a std::vector<T*> should work. Indeed, a new class will be created for each instantiation of MemoryManaged. This means that MemoryManaged<Foo> and MemoryManaged<Bar> will be totally different types. Consequently, the static member container will not be common to these two classes. It will be as if you had the two following classes:
class MemoryManagedFoo
{
MemoryManagedFoo()
{
//Here, you know that 'this' is a Foo*
container.push_back(this); //ok, we add 'this' to a container of Foo*
}
static std::vector<Foo*> container;
};
class MemoryManagedBar
{
MemoryManagedBar()
{
//Here, you know that 'this' is a Bar*
container.push_back(this); //ok, we add 'this' to a container of Bar*
}
static std::vector<Bar*> container;
};
As you can see, the static member is not shared by the two instantiations.
Of course, this solution assumes that MemoryManaged will always be used using CRTP, as you described in your question. In other word, this code will work:
class Foo : public MemoryManaged<Foo> { };
but not this one:
class Foo : public MemoryManaged<Bar>
{
// Here, 'container' is a 'vector<Bar*>' and 'this' is a Foo * --> problem
};

Using a C++ child class instance as a default parameter?

So I have a couple classes defined thusly:
class StatLogger {
public:
StatLogger();
~StatLogger();
bool open(<parameters>);
private:
<minutiae>
};
And a child class that descends from it to implement a null object pattern (unopened it's its own null object)
class NullStatLogger : public StatLogger {
public:
NullStatLogger() : StatLogger() {}
};
Then I have a third class that I want to take an optional logger instance in its constructor:
class ThirdClass {
public:
ThirdClass(StatLogger& logger=NullStatLogger());
};
My problem is when I do it as above, I get:
error: default argument for parameter
of type ‘StatLogger&’ has type
‘NullStatLogger’
And if I put an explicit cast in the definition, I get:
error: no matching function for call
to
‘StatLogger::StatLogger(NullStatLogger)
Complaining about not having a constructor from a NullStatLogger even though it's a child class. What am I doing wrong here, is this allowed in C++?
I you want to use inheritance and polymorphism, ThirdClass needs to use either a pointer or a reference to StatLogger object, not with an actual object. Likewise, under the circumstances you almost certainly need to make StatLogger::~StatLogger() virtual.
For example, modified as follows, the code should compile cleanly:
class StatLogger {
public:
StatLogger();
virtual ~StatLogger();
// bool open(<parameters>);
private:
// <minutiae>
};
class NullStatLogger : public StatLogger {
public:
NullStatLogger() : StatLogger() {}
};
class ThirdClass {
StatLogger *log;
public:
ThirdClass(StatLogger *logger=new NullStatLogger()) : log(logger) {}
};
Edit: If you prefer a reference, the code looks something like this:
class StatLogger {
public:
StatLogger();
virtual ~StatLogger();
// bool open(<parameters>);
private:
// <minutiae>
};
class NullStatLogger : public StatLogger {
public:
NullStatLogger() : StatLogger() {}
};
class ThirdClass {
StatLogger &log;
public:
ThirdClass(StatLogger &logger=*new NullStatLogger()) : log(logger) {}
};
Based on the discussion in Jerry's answer, what about simplifying the problem by not using a default variable at all:
class ThirdClass
{
StatLogger log;
public:
ThirdClass() : log(NullLogger()) {}
ThirdClass(const StatLogger& logger) : log(logger) {}
};
There is no problem in using a derived instance as default argument for a base reference.
Now, you cannot bind a non-constant reference to a temporary (rvalue) which can be one reason for the compiler to complain about your code, but I would expect a better diagnose message (cannot bind temporary to reference or something alike).
This simple test compiles perfectly:
class base {};
class derived : public base {};
void f( base const & b = derived() ) {} // note: const &
int main() {
f();
}
If the function must modify the received argument consider refactoring to a pointer and provide a default null value (not a default dynamically allocated object).
void f( base * b = 0) {
if (b) b->log( "something" );
}
Only if you want to keep the non-const reference interface and at the same time provide a default instance, then you must provide an static instance, but I would recommend against this:
namespace detail {
derived d;
// or:
derived & null_logger() {
static derived log;
return log;
}
}
void f( base & b = detail::d ) {}
// or:
void g( base & b = detail::default_value() ) {}
Well for a default value I believe you have to provide a default value...
ThirdClass(StatLogger *logger = NULL)
for example
Uh, I know this is an oooold question, but I just had the exact same problem, and after reading all the proposed answers and comments, I came up with a slightly different solution.
I think it also might just be appropriate for the problem instance presented here, so here it goes:
Make the NullStartLogger a singleton type of object!
For me, it was quite elegant and sort. Very shortly, singleton is an object that you can not construct at will, since only and exactly one instance can exist at all time. (Alternatively, there might be 0 instances before the first usage, since you can postpone the initialization). You can of course only add the singleton functionality in to your derived class, while all the other instances (and derivations) of the parent class can be initialized and created normally. But, if NullStatLogger is, as it was in my case, just a dummy class, it does not store any data externally and does not have different behavior depending on the instance/init parameters, singleton class fits well.
Here's a short code snipped making your NullStatLogger a singleton, as well as a way to use it in the ThirdClass:
class NullStatLogger : public StatLogger {
private:
NullStatLogger() : StatLogger() {}
static NullStatLogger *_instance;
public:
static NullStatLogger &instance();
};
NullStatLogger::_instance = 0;
NullStatLogger &NullStatLogger:instance() {
if (_instance == 0)
_instance = new NullStatLogger(); // constructor private, this is
// the only place you can call it
return *_instance; // the same instance always returned
}
class ThirdClass {
public:
ThirdClass(StatLogger& logger=NullStatLogger::instance());
};
I know this surely won't help to whomever asked the question, but hopefully it helps someone else.

Non static members as default parameters in C++

I'm refactoring a large amount of code where I have to add an extra parameter to a number of functions, which will always have a value of a member of that object. Something like
class MyClass
{
public:
CMyObject A,B;
void MyFunc(CMyObject &Object);
// used to be void MyFunc();
};
Now, I'd actually like it to read
class MyClass
{
public:
CMyObject A,B;
void MyFunc(CMyObject &Object = A);
};
But I'm not allowed to have a default parameter that is a non-static member. I've read this similar question which suggest this isn't possible, but I'm wondering if there is any reasonable workaround. Reason being that 95% of the time the default parameter will be used, and thus using a default parameter would hugely reduce the amount of code I have to change. My best solution so far is something like this;
class MyClass
{
public:
CMyObject A,B;
void MyFunc(BOOL IsA = TRUE);
};
void MyClass::MyFunc(BOOL IsA)
{
CMyObject &Object = A;
if (!IsA)
Object = &B;
}
This is less than elgant, but is there a better way of doing this that I'm missing?
Edit: FWIW, the reason for the extra parameter is to externalize some state related members from the object in question to aid multi-threading.
How about :
class MyClass
{
public:
CMyObject A,B;
void MyFunc()
{
MyFunc(A);
}
void MyFunc(CMyObject &Object);
};
?
Another way:
class MyClass
{
public:
MyObject A,B;
void MyFunc(MyObject MyClass::*myObject = &MyClass::A) {
MyObject& obj = *(this->*myObject);
}
};
This makes it even impossible to pass in an MyObject member from another MyClass instance. Your three valid options to call MyFunc are .MyFunc(), .MyFunc(&MyClass::A) and .MyFunc(&MyClass::B)