Thursday, January 22, 2009

[C#, C++] Cascading Constructors

In C# you can call a constructor of your class from another constructor of the same class to do something like this:

class Cake
{
private string name;
private int price;

public Cake(int price, string cakeName)
{
this.name = cakeName;
this.price = price;
//init stuff
}

public Cake(int price):this(price, "Cheesecake")
{
//init other stuff
}
}

Unfortunately there's no way to do this in good old C++, but there are two common ways for simulating a similar behavior:

1) Combine two (or more) constructors via default/optional parameters:

class Cake
{
private:
string name;
int price;

public:
//combines Cake() and Cake("whatever")
Cake(int price, string name = "Cheesecake Giovacchia")
{
this->name = name;
this->price = price;
}
}

2) Use an Init method to share common code:

class Cake
{
private:
int price;
string name;

init(int price, string name)
{
//do crazy common stuff with price and name
}

public:
Cake(int price)
{
this->init(price, "Cheesecake Giovacchia");
}

Cake(int price, string cakeName)
{
this->init(price, cakeName);
}

}

That's about it, I prefer the first solution (the second kinda sucks) but if anyone knows better I am all ears.

I am done sucking for today.

2 comments:

Venus said...

thanks - it helped

bil said...

Another option is to use inheritance.

#include <string>
#include <iostream>
using namespace std;

class BakeryItem
{
private:
string name;
int price;

public:
BakeryItem(int price, string cakeName) : name(cakeName), price(price)
{
//init stuff
}

friend std::ostream& operator<<(std::ostream& os, BakeryItem& b)
{
os << "name: " << b.name << ", price: " << b.price;
return os;
}
};

class Cake : public BakeryItem
{
public:
Cake(int price, string cakeName) : BakeryItem(price, cakeName) {};
Cake(int price) : BakeryItem(price, "Cheesecake") {};
};

int main(int argc, char* argv[])
{
Cake carrot(125, "Carrot");
std::cout << carrot << endl;
Cake cheese(250);
std::cout << cheese << endl;
return 0;
}

// the derived class defines the same constructors as the base class but it just forwards the work to the base class constructor