Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/tfs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 课堂设计的困境_C++ - Fatal编程技术网

C++ 课堂设计的困境

C++ 课堂设计的困境,c++,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

我想得到一些关于在类似下面例子的情况下设计类的建议。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;
}
类号组件
{
公众:
//没有数字组件的对象只存储空指针。
//任何时候我们在这里做任何事情,都必须确保p_int不为null。
NumberComponent():p_int(0){}
NumberComponent(int x){p_int=new int(x);}
~NumberComponent(){delete p_int;}
void DoSomething(){if(p_int)++(*p_int);}
//在实际情况中,这将是另一个复杂的类对象。
//例如,在这里使用int*使这个类保持简单。
int*p_int;
};
//B对象可能有也可能没有数字组件。
B类:公共数字组件
{
公众:
//如果hasNumberComponent为false,我们将调用默认构造函数。
//如果hasNumberComponent为true,我们将调用NumberComponent(int)构造函数。
B(int x,bool hasNumberComponent){}
int值;
};
//C对象可能有也可能没有数字组件。
C类:公共数字组件
{
公众:
//如果hasNumberComponent为false,我们将调用默认构造函数。
//如果hasNumberComponent为true,我们将调用NumberComponent(int)构造函数。
C(int x,bool hasNumberComponent){}
int值;
};
int main()
{
//myList包含B和C对象的NumberComponent*
std::列表myList;
myList.push_back(新的B(5,true));
myList.push_back(新的C(3,true));
对于(std::list::迭代器i=myList.begin();i!=myList.end();++i)
(*i)->DoSomething();
//这些对象没有数字组件。
B(2,假);
C(1,假);
返回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;
};

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

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;
};

如果
B
C
源自
NumberComponent
,则它们是
NumberComponent
s。因此,说它们“可能有数字成分,也可能没有数字成分”是没有意义的。顺便说一句:除非必须,否则不要使用动态分配的对象(即通过
new
)。我看不出有任何理由在示例代码中使用
new
!我想我有点困惑我是怎么想的。我希望一些B和C对象有一个p_int,并且能够执行DoSomething()之类的操作。其他B和C对象将是相同的,只是它们不需要p_int,并且不能执行DoSomething()之类的操作。那么它们就不是同一类型的对象。类的全部要点在于它描述了该类所有对象的行为。如果您想让不同的对象做不同的事情,那么它们需要属于不同的类。@user987280:将相同的功能放在基类中,从它们继承,并在派生类中添加额外的功能。这似乎是更好的设计方法,除了我不能有一个使用NumberComponent的std::对象列表。我希望能够有一个具有NumberComponent功能的B和C对象的列表,这样我就可以对它们调用DoSomething()。我认为唯一的方法是让B和C都继承自同一父类。@user987280相同的父类,但不一定是
NumberComponent
,这似乎是对象的某种额外功能。通过降低结构提供给属性的额外接口(如果为false,则不会发生任何事情),可以将结构展平。也不要把你的物品的责任搞乱。如果您需要
B
C
的一些常用方法,那么使用抽象虚拟方法
dosomethinterface()
定义纯抽象类
dosomethinterface
,继承此方法并在
B
C
中实现。