Conversion of function parameter to child class c++ - c++

I have a parent class with a non virtual interface (NVI):
class Parent {
private:
virtual int do_function(void) = 0;
public:
int function(void);
virtual ~Parent() {};
}
And a child class (actually, I have a lot of child classes, but I want only this one to work this way)
class Child : public Parent {
private:
int _x;
int do_function(void) { return _x; };
public:
Child(int x): Parent(), _x(x) {}
virtual ~Child() {return do_function();};
}
And I want to call a function:
int myFunction(Parent& x) {
return x.function();
}
using the code
int x = 5;
myFunction(x);
but not the
int myFunction(const Child& x) {
return x.function();
}
which works fine.
Is it possible to do this with implicit conversion of types?

Basically you want to implicitly create a Child Object, constructed with x, and then have it passed through to myFunction( Parent& ).
You can do myFunction(Child(x));
but I think that when you try with the bare x, it tries to construct a object : Parent(x) and it fails. That isn't what you want anyway because you do want an instance of a Child object.
The way that make_pair does something similar is using a templated copy constructor on the object that is being created (pair) which creates an object of the required type(s).
I think that what you want to do can't be done in that way because you want to create the derived class and it isn't going to try to do that because the function signature is Parent&.
edit and alternative solution
I made a few attempts to create a template based solution to this by adding a templated constructor to the Parent class but it really does boil down to the fact that ultimately you need to invoke a constructor for the derived class.
I think the only sensible solution to this to allow use of the myFunction(Parent&) is to use an Indirect method that returns a reference to a Parent after constructing (temporary?) the child - that of course means you would have many such methods if you have many child classes. I realise that this is not quite as simple as passing in the int (and having it construct and pass in the ref), but it is almost what you want :)

Related

c++: inherit constructor, but change by editing methods called within constructor

Suppose I have a base class,
struct X{
std::container<class> A;
std::container<class> B;
void do_this(...){...};
void do_that(...){...};
X(classC something){
do_this(...);
do_that(...);
}
}
And I want to create a descendant, but I need to only change a couple of lines in one of the methods called in the constructor:
struct Y:X{
void do_this(...){
// make my changes
}
}
Now, when I call Y(classC input), I should get my Y struct as intended, right?
How would I do this in C++?
Now, when I call Y(classC input), I should get my Y struct as intended, right?
Wrong. Inheriting a constructor doesn't mean its body is recreated with the function calls substituted by the ones you overload. It means that to construct a Y it is sufficient to construct the X sub-object explicitly via that c'tor. So rather than hassling you with forwarding stuff, you pull the appropriate c'tor into Y to be used.
This means, same c'tor body. And everything else that is Y specific will be default initialized.
How would I do this in C++?
Simply put, you can't do it easily. Unless you mess around with dark template magic, X::X will always call X::do_this. You could also move do_this to some other class, and use that one polymorphically, but as you mentioned, this isn't an option.
If you want to add a call to Y::do_this, then write a c'tor for Y. But it won't replace the call to X::do_this, it will happen afterwards. That's the C++ object model.
As long as class Y inherits from class X and class X doesn't have a default constructor you must call its overloaded version explicitly in the overloaded class (Y):
class X{
public:
X(int _x) : x(_x){};
private:
int x;
};
class Y : public X{
public:
Y() : X(0){} // important
};
int main() {
Y y; // if you remove the default constructor of Y you'll get an error here
return 0;
}
This is tough, because the only good method would be to use virtual functions. This is however not feasible here, because virtual methods in constructors are resolved statically. This means, that if you have class A and class B : A and both of them have implemented virtual function foo, when you call foo in base class constructor it will always use base class implementation.
The one method is to use it like this:
class A {
public:
A(whatever) { }
virtual void initialize() {
// base class impl
}
};
class B : public A{
public:
// if no base default ctor, use
// B(whatever)
// : A(whatever)
B(whatever) {
}
virtual void initialize() override {
// derived class impl
}
};
template <typename T> // constraint it if you want.
T createObject() {
T object;
object.initialize(); // resolved dynamically
}

Constructor of a subclass of a template-instantiated abstract base class - alternative design patterns required

I have a template like this:
template<typename T>
struct foo {
foo(T t) {
//code
}
virtual double computation() = 0;
//other members
};
I want users to provide their own subclasses with a custom T and computation() like this:
struct my_foo : public foo<std::string> {
double computation() override { return 9.99; }
};
The problem is that this doesn't work:
my_foo("hello");
I would have to ask users to create a new constructor for every subclass, even if all it does is call the superclass constructor. This looks silly.
Can you suggest alternative "design patterns" that may be more suitable for me?
I believe it has no direct relationship with template.
It is simply due to: in C++, constructor is not inherited.
Try this example and you will see it does not work:
class Parent {
public:
Parent(int i) {
cout << "i " << i << endl;
};
};
class Child : public Parent {
};
int main(int argc, char** args) {
Child child(1);
return 0;
}
because by default, constructor of Child will call Parent's no-arg ctor. However no-arg ctor is not available in Parent.
Change Child to provide proper ctor will solve the problem:
class Child : public Parent {
public:
Child(int i):Parent(i) {
}
};
In this example, I created a ctor for Child which takes 1 param. This Child ctor will invoke Parent's Parent(int) ctor.
In your question, you said it is silly to ask Child classes to create the ctor: It is not silly at all! You will never know how the child wants its class to be instantiated. Certain child class may only be reasonable to be constructed with 2 parameters for ctor base on its semantic meaning.
If you really really want it to be done magically, one simplest way you can do is to create macros to "generate" the class declaration and corresponding ctor for the child class. However it is seldom meaningful to do so.
As far as I can see from your example, you want the user to specify a type and a computation function. Since you did not provide a virtual destructor, I assume that you don not want to use the resulting template instantiations polymorphically, e.g. you don't want to store/exchange different foo<string> implementations in the same place. In other words, the only purpose of the pure virtual function seems to make the implementation of computation() by the client mandatory.
You further want the constructor of your template be usable without the client having to reimplement or explicitly import it to his class. That can be achieved only if my_foo is an instance of foo and not a derived class.
In that case, you could use policy based design:
template<typename T, typename ComputationPolicy>
struct foo : ComputationPolicy {
foo(T t) {
//code
}
void bar() {
double d = ComputationPolicy::computation(); //just use it!
}
//...
};
Users of the template now have to define a type that has a function computation(), returning a value convertible to double, otherwise the template can't be instantiated:
struct myComp {
double computation() { return 9.99; }
};
typedef foo<std::string, myComp> my_foo;
my_foo("hello");

QSharedData and inheritance

I'm trying to make a type system while using QSharedData. The idea is simple, there will be a number of different data types, each of which is going to be derived from the base abstract class. I want to use QSharedData to store the actual data in each of them, but each of the derived classes is going to have different data stored inside. I'm trying to make the most basic example now, and having some troubles.
Let's say these are my base pure virtual classes:
class cAbstractData: public QSharedData
{
public:
cAbstractData(){ }
virtual int type() = 0;
};
class cAbstractValue
{
public:
cAbstractValue(){ }
virtual int type() = 0;
protected:
QSharedDataPointer<cAbstractData>data_;
};
Now let's say I want to make a class for representing a single value (as a minmalistic example that is). I'm deriving the cAtomicValue from the base value class, and I am also deriving a data class to hold the value:
class cAtomicData:public cAbstractData
{
public:
cAtomicData() { value_ = 0; }
int type(){ return 1; }
QVariant value_;//the actual value
};
class cAtomicValue:public cAbstractValue
{
public:
cAtomicValue() {
data_ = new cAtomicData;//creating the data object.
}
int type(){ return 1; }
};
Now at this stage it works just fine, and in the debugger I can see the right pointer type. But now I want to add a function for setting and getting the value, and I fail to understand how to do it. Let's take the setter as an example. To set the value, we must access the value_ member of cAtomicData class through the data_ member of the cAtomicValue class. However since the data_ holds a base-class pointer (cAbstractData), I'll have to cast it to the right type (cAtomicData) somehow. I tried doing this:
template<class T> void set( T value )
{
static_cast<cAtomicData*>(data_.data())->value_ = value;
}
it obviously doesn't work, because it called detach() and tries to make a copy of the base class which it can't since the base class is pure virtual. Then I tried to cast the pointer itself:
static_cast<cAtomicData*>(data_)->value_ = value;
but I'm getting an invalid static_cast ... error.
How do I do it, and am I even doing it the right way fundamentally?
You can switch to QExplicitlySharedDataPointer instead of QSharedDataPointer. In that way detach() won't be called whenever you're trying to obtain a non-const pointer to the cAbstractData object, which includes casting the QExplicitlySharedDataPointer<cAbstractData> object to a QExplicitlySharedDataPointer<cAtomicData> object. However, you will need to call detach() manually every time you want to make a modification to the cAbstractData if you are going to use copy-on-write. Maybe you can write a wrapper class to perform the detaching for you.
This method may be prefered over using QSharedPointer, since a QExplicitlySharedDataPointer is the same size as a normal pointer (and hence keeps binary compability) while a QSharedPointer is twice the size (see this blog entry).
Edit: Note that the cast from QExplicitlySharedDataPointer<cAbstractData> to QExplicitlySharedDataPointer<cAtomicData> is static, so you will have to guarantee that the object that is referenced actually is an object of the type cAtomicData (or of a subclass), or the behavior when using the pointer might be undefined.
I had a similar problem in my application and here is how I solved it. I have a BaseClass that is implemented using the Pimpl idiom and QExplicitlySharedDataPointer pointing to BaseClassPrivate. This class is inherited by DerivedClass whose private member is a DerivedClassPrivate inheriting BaseClassPrivate.
BaseClassPrivate has one float member named baseParam and DerivedClassPrivate has another float parameter named derivedParam.
I solved this problem doing the following :
Define a protected constructor BaseClass(BaseClassPrivate* p)
This is used to instantiate new derived classes with a pointer to DerivedClassPrivate
Define a virtual clone() method in both BaseClassPrivate and DerivedClassPrivate
This method is called to correctly copy the private class whenever a deep copy is needed. So, instead of calling 'QExplicitlySharedDataPointer::detach()', we check if the QSharedData reference counter is greater than 1, and then we call clone. Please note that QSharedData::ref is not in the documentation so this can change anytime (even though it seems unlikely to happen soon).
Static cast the d pointer in DerivedClass
I find it convenient to define a private dCasted() function.
To test this the virtual function foo() is introduced in BaseClassPrivate and DerivedClassPrivate, which returns either baseParam or derivedParam accordingly.
Here is the code :
BaseClass.h
class BaseClass
{
public:
BaseClass() : d(new BaseClassPrivate()) {}
BaseClass(const BaseClass& other) : d(other.d) {}
BaseClass& operator =(const BaseClass& other) {d = other.d; return *this;}
virtual ~BaseClass() {}
float baseParam() const {return d->baseParam;}
void setBaseParam(float value) {
detach(); // instead of calling d.detach()
d->baseParam = value;
}
float foo() const {return d->foo();}
protected:
BaseClass(BaseClassPrivate* p) : d(p) {}
void detach() {
// if there's only one reference to d, no need to clone.
if (!d || d->ref == 1) return; // WARNING : d->ref is not in the official Qt documentation !!!
d = d->clone();
}
QExplicitlySharedDataPointer<BaseClassPrivate> d;
};
DerivedClass.h
class DerivedClass : public BaseClass
{
public:
DerivedClass() : BaseClass(new DerivedClassPrivate()) {}
float derivedParam() const {return dCasted()->derivedParam;}
void setDerivedParam(float value) {
detach(); // instead of calling d.detach();
dCasted()->derivedParam = value;
}
private:
DerivedClassPrivate* dCasted() const {return static_cast<DerivedDataPrivate*>(d.data());}
};
BaseClassPrivate.h
class BaseClassPrivate : public QSharedData
{
public:
BaseClassPrivate() : QSharedData(), baseParam(0.0) {}
BaseClassPrivate(const BaseClassPrivate& other) :
QSharedData(other), baseParam(other.baseParam) {}
virtual ~BaseClassPrivate() {}
float baseParam;
virtual float foo() const {return baseParam;}
virtual BaseClassPrivate* clone() const {
return new BaseClassPrivate(*this);
}
};
DerivedClassPrivate.h
class DerivedClassPrivate : public BaseClassPrivate
{
public:
DerivedClassPrivate() : BaseClassPrivate(), derivedParam(0.0) {}
DerivedClassPrivate(const DerivedClassPrivate& other) :
BaseClassPrivate(other), derivedParam(other.derivedParam) {}
float derivedParam;
virtual float foo() const {return derivedParam;}
virtual BaseClassPrivate* clone() const {
return new DerivedClassPrivate(*this);
}
};
Now, we can do things such as :
Call virtual functions :
DerivedClass derived;
derived.setDerivedParam(1.0);
QCOMPARE(derived.foo(), 1.0); // proving that DerivedClassPrivate::foo() is called
Make copies from DerivedClass to BaseClass correctly :
BaseClass baseCopy = derived;
QCOMPARE(baseCopy.foo(), 1.0); // proving that DerivedClassPrivate::foo() is called
// even after copying to a BaseClass
Make copies from BaseClass to BaseClass respecting the original class and also make a copy-on-write correctly :
BaseClass bbCopy(baseCopy); // make a second copy to another BaseClass
QCOMPARE(bbCopy.foo(), 1.0); // still calling DerivedClassPrivate::foo()
// copy-on-write
baseCopy.setBaseParam(2.0); // this calls the virtual DerivedClassPrivate::clone()
// even when called from a BaseClass
QCOMPARE(baseCopy.baseParam(), 2.0); // verify the value is entered correctly
QCOMPARE(bbCopy.baseParam(), 1.0); // detach is performed correctly, bbCopy is
// unchanged
QCOMPARE(baseCopy.foo(), 1.0); // baseCopy is still a DerivedClass even after detaching
Hope this helps
I don't see any way to achieve what you're attempting here. As you've discovered, QSharedDataPointer needs to be templated on the actual type it contains.
You could make your base class a template, e.g.
template<class T>
class cAbstractValue
{
public:
cAbstractValue(){ }
virtual int type() = 0;
protected:
QSharedDataPointer<T> data_;
};
But I'm not sure I see what benefit you would get from that.
Since Qt 4.5 you can implement the ::clone() function for your type:
This function is provided so that you may support "virtual copy constructors" for your own types. In order to so, you should declare a template-specialization of this function for your own type, like the example below:
template<>
EmployeeData *QSharedDataPointer<EmployeeData>::clone()
{
return d->clone();
}
In the example above, the template specialization for the clone() function calls the EmployeeData::clone() virtual function. A class derived from EmployeeData could override that function and return the proper polymorphic type.
This function was introduced in Qt 4.5.
I've done so and it works.
Either your abstract base class and all derived classes need to implement a virtual BaseClass* clone() function you'd call from QSharedDataPointer::clone() or you need some other method (e.g. factory) to create a new instance with the same content as d.

is it okay to pass member variables as parameters to member functions in C++?

I also have a similar design question now in my work assignment. I have a base class like
class base
{
protected:
update()
{
// do some stuff with a and b, call it as action A
}
int a, b;
};
class derived : public base
{
protected:
update()
{
// want to do the same action A , but with varaiables c and d
}
int c, d;
};
and the requirement is, derived class requires both the operations , such as action on "a and b" AND "c and d" aslo. Hence , is it okay to design a method like update(int, int) , so that I can pass parameters as and when required "a and b" AND "c and d" and perform action on them .And I know that I can write a helper method to perform that action, but this action is specific to this class I cant separate it from this. Can I have any other better alternative for this.
In realtime its a bigger class and the action also not on integers ,its on some objects in turn, and the varibales should be related to the class.
You can call the base class implementation from the derived class implementation. Just call base::update(). Look here for example.
Yes that is perfectly valid:
class base
{
protected:
void update()
//^^^^ You forgot the return type.
{
doUpdate(a, b);
}
void doUpdate(int& x, int& y)
{
// do some stuff with x and y
// Because x and y are passed by reference they affect the original values.
}
private: // Should probaly make the member vars private
int a, b;
};
class derived : public base
{
protected:
void update()
//^^^^ You forgot the return type.
{
doUpdate(c, d);
}
private: // Should probaly make the member vars private
int c, d;
};
I would revisit whether your class derived has an is-a relationship (as you show) or a has-a relationship, like this:
class contains
{
protected:
base x, y;
update() { x.update(); y.update(); }
};
What you're asking is technically feasible, just define
void update(int& a, int &b)
and inside the update body forgot about the class memebrs and always refer to the parameters and call it as
update(a,b) or update(c,d).
The point, here, is to understand if update is really a member function (that requires also to access other member variables) or just a static member (that leaves in the class space, but doesn't see class members itself) and if the relation between the classes is correct (that merely means embedding vs inheritance). But these aspects should be based on consideration other than just the ones related on a single call...

Call a base class constructor later (not in the initializer list) in C++

I'm inheriting a class and I would like to call one of its constructors. However, I have to process some stuff (that doesn't require anything of the base class) before calling it. Is there any way I can just call it later instead of calling it on the initializer list? I believe this can be done in Java and C# but I'm not sure about C++.
The data that I need to pass on the constructor can't be reassigned later, so I can't just call a default constructor and initialize it later.
Is there any way I can just call it later instead of calling it on the initializer list?
No, you cannot. The base class constructor must be called in the initializer list, and it must be called first.
In fact, if you omit it there, the compiler will just add the call implicitly.
I believe this can be done in Java and C# but I'm not sure about C++.
Neither C# nor Java allow this either.
What you can do, however, is call a method as an argument of the base class constructor call. This is then processed before the constructor:
class Derived {
public:
Derived() : Base(some_function()) { }
private:
static int some_function() { return 42; }
};
As was said by several people answering, you cannot delay the invocation of a base class constructor, but Konrad has given a good answer that might well solve your problem. However, this does have its drawbacks (for example, when you need to initialize several functions with values whose calculations share intermediate results), so just to be complete, here's another way of solving the problem of fixed initialization order, by using it.
Given the fixed order of initialization, if you have control over the derived class (and how else would you come to fiddle with one of its ctors?), you can sneak in a private base so that it is going to be initialized before the other base, which can then be initialized with the private base's already calculated values:
class my_dirty_little_secret {
// friend class the_class;
public:
my_dirty_little_secret(const std::string& str)
{
// however that calculates x, y, and z from str I wouldn't know
}
int x;
std::string y;
float z;
};
class the_class : private my_dirty_little_secret // must be first, see ctor
, public the_other_base_class {
public:
the_class(const std::string str)
: my_dirty_little_secret(str)
, the_other_base_class(x, y, z)
{
}
// ...
};
The my_dirty_little_secret class is a private base so that users of the_class cannot use it, all of its stuff is private, too, with explicit friendship granting only the_class access to it. However, since it's listed first in the base class list, it will reliably be constructed before the_other_base_class, so whatever it calculates can be used to initialize that.
A nice comment at the base class list hopefully prevents from others breaking things by refactoring.
IMHO I dont think it is possible to defer calling the base class constructor in the way that you mentioned.
Wow, we were all young once. This answer won't work, so don't use it. Content left for historical purposes.
If you have full control over the base class, I'd recommend adding a protected method to do the class initialization, make it virtual, and put the your derived class implementation details in it before it calls its base:
class Base
{
public:
Base()
{
Initialize();
}
protected:
virtual void Initialize()
{
//do initialization;
}
};
class Derived : Base
{
public:
Derived() : Base()
{
}
protected:
virtual void Initialize()
{
//Do my initialization
//call base
Base::Initialize();
}
};
Another option, based on the suggestion from #Konrad is to have a static method to construct the object, e.g.:
class Derived {
public:
Derived(int p1, int p2, int p3) : Base(p1, p2) { }
static Derived* CreateDerived(int p3) { return new Derived(42, 314, p3); }
};
Ive found this useful when extending a class from a library and having multiple parameters to override.
You can even make the constructor private
struct base{
base(int x){}
};
struct derived : base{
derived(int x) : base(x){}
};
This is how base class constructors are invoked in C++ from the initialization list of derived class.