班级设计困境

时间:2012-03-03 22:05:51

标签: c++

我想在类似于下面示例的情况下获得有关设计类的建议。 B和C对象可能有也可能没有数字组件。问题是没有办法有选择地调用NumberComponent构造函数。有没有更好的方法来设计它?

class NumberComponent
{
public:
//Objects which don't have a number component just store a null pointer.
//Any time we do anything here, we have to make sure p_int isn't null.
NumberComponent() : p_int(0) { }
NumberComponent(int x) { p_int = new int(x); }
~NumberComponent() { delete p_int; }

void DoSomething() { if(p_int) ++(*p_int); }

//In real situation, this will be another complex class object.
//Using an int* here to keep this class simple for example.
int* p_int;
};

//B objects may or may not have a number component.
class B : public NumberComponent
{
public:
//If hasNumberComponent is false, we'd like to call the default constructor.
//If hasNumberComponent is true, we'd like to call NumberComponent(int) constructor.
B(int x, bool hasNumberComponent) {}

int value;
};

//C objects may or may not have a number component.
class C : public NumberComponent
{
public:
//If hasNumberComponent is false, we'd like to call the default constructor.
//If hasNumberComponent is true, we'd like to call NumberComponent(int) constructor.
C(int x, bool hasNumberComponent) {}

int value;
};

int main()
{
//myList contains NumberComponent* to B and C objects 
std::list<NumberComponent*> myList;

myList.push_back(new B(5, true));
myList.push_back(new C(3, true));

for(std::list<NumberComponent*>::iterator i = myList.begin(); i != myList.end(); ++i)
    (*i)->DoSomething();

//These objects don't have a Number component.
B b(2, false);
C c(1, false);

return 0;
}

2 个答案:

答案 0 :(得分:0)

虽然有更好的设计,但您可以解决这个问题:

class NumberComponent
{
public:
NumberComponent(int x,bool hasNumberComponent)
  : p_int(hasNumberComponent ? new int(x) : 0) { }
~NumberComponent() { delete p_int; }

void DoSomething() { if(p_int) ++(*p_int); }

//In real situation, this will be another complex class object.
//Using an int* here to keep this class simple for example.
int* p_int;
};

//B objects may or may not have a number component.
class B : public NumberComponent
{
public:
B(int x, bool hasNumberComponent) : NumberComponent(x,hasNumberComponent) {}

int value;
};

//C objects may or may not have a number component.
class C : public NumberComponent
{
public:
C(int x, bool hasNumberComponent) : NumberComponent(x,hasNumberComponent) {}

int value;
};

答案 1 :(得分:0)

这里有很多不好的设计。您是否考虑过将继承用于它的发明:

class B
{
   public:
      B(int x):
         m_val(x)
      {
      }

      virtual void doSomething()
      {
          //something
      }

   private: //might be protected as well
       m_val;
};

class BWithNumberComponent : public B
{
   public:
     BWithNumberComponent(int x):
         B(x),
         m_numberComponent(x)
     {
     }

     virtual void doSomething()
     {
       //something else
     }

   private:
     NumberComponent m_numberComponent;
};