C++ c++;确保将对象指定给一组对象
我在写一个建模与仿真程序时遇到了一个设计问题。模型的所有组件都被组织成一个树型数据结构,为了使其工作,每个组件都需要有一个指向其父对象的指针。为了避免技术细节,我做了一个类比: 我有一个处理所有树功能的基类:C++ c++;确保将对象指定给一组对象,c++,C++,我在写一个建模与仿真程序时遇到了一个设计问题。模型的所有组件都被组织成一个树型数据结构,为了使其工作,每个组件都需要有一个指向其父对象的指针。为了避免技术细节,我做了一个类比: 我有一个处理所有树功能的基类: class node {}; 以及以下表示仿真组件的派生类: class turtle : public node {}; class clam : public node {}; class dog : public node {}; class leg : public node
class node {};
以及以下表示仿真组件的派生类:
class turtle : public node {};
class clam : public node {};
class dog : public node {};
class leg : public node {
node* _parent;
/*Some functions relevant to a leg*/
};
class shell : public node {
node* _parent;
/*Some functions relevant to a shell*/
};
还有其他子组件:
class turtle : public node {};
class clam : public node {};
class dog : public node {};
class leg : public node {
node* _parent;
/*Some functions relevant to a leg*/
};
class shell : public node {
node* _parent;
/*Some functions relevant to a shell*/
};
我的问题是,我想确保腿只分配给乌龟或狗,壳只分配给乌龟或蛤蜊。dog类没有处理shell
类型的子类的功能,同样,clam也不能处理leg
类型的子类
我正在考虑制作
shell
和leg
类模板,它们的父类型将是模板参数。然后,我可以只为我希望每个类具有的父类型专门化构造函数模板。这是解决这个问题的好方法,还是我应该看一些其他C++特性? 您可以为可用的功能和属性提供接口,并根据需要将它们混合在一起。在C++中使用纯虚函数< /P>创建接口
class leg;
class shell;
struct IAnimalWithShell {
void addShell(shell* shell) = 0;
~IAnimalWithShell() = default;
};
struct IAnimalWithLegs {
void addLegs(const std::vector<leg*>&) = 0;
~IAnimalWithLegs() = default;
};
类腿;
类外壳;
结构IAnimalWithShell{
void addShell(shell*shell)=0;
~IAnimalWithShell()=默认值;
};
结构IAnimalWithLegs{
void addLegs(const std::vector&)=0;
~IAnimalWithLegs()=默认值;
};
class-turtle:public节点、public IAnimalWithShell、public IAnimalWithLegs{
// ...
公众:
void addShell(shell*shell){
//实施
}
void addLegs(const std::vector和legs){
//实施
}
};
clam类:公共节点,公共IAnimalWithShell{
// ...
公众:
void addShell(shell*shell){
//实施
}
};
class-dog:public节点,公共IAnimalWithLegs{
// ...
公众:
void addLegs(const std::vector和legs){
//实施
}
};
我希望你能明白
当您要求设计时,以下是一些相关的模式
这些讨论了如上所述的结构化设计的后果。您可以为可用的功能和属性提供接口,并根据需要将它们混合在一起。在C++中使用纯虚函数< /P>创建接口
class leg;
class shell;
struct IAnimalWithShell {
void addShell(shell* shell) = 0;
~IAnimalWithShell() = default;
};
struct IAnimalWithLegs {
void addLegs(const std::vector<leg*>&) = 0;
~IAnimalWithLegs() = default;
};
类腿;
类外壳;
结构IAnimalWithShell{
void addShell(shell*shell)=0;
~IAnimalWithShell()=默认值;
};
结构IAnimalWithLegs{
void addLegs(const std::vector&)=0;
~IAnimalWithLegs()=默认值;
};
class-turtle:public节点、public IAnimalWithShell、public IAnimalWithLegs{
// ...
公众:
void addShell(shell*shell){
//实施
}
void addLegs(const std::vector和legs){
//实施
}
};
clam类:公共节点,公共IAnimalWithShell{
// ...
公众:
void addShell(shell*shell){
//实施
}
};
class-dog:public节点,公共IAnimalWithLegs{
// ...
公众:
void addLegs(const std::vector和legs){
//实施
}
};
我希望你能明白
当您要求设计时,以下是一些相关的模式
这些讨论了上述结构设计的后果。我个人会将约束检查代码转移到专用的工厂类,例如:
class TurtleFactory {
public:
node * newTurtle() const {
node * t = new turtle;
for (int i = 0; i < 4; ++i)
t->addChild(new leg);
t->addChild(new shell);
return t;
}
friend class turtle;
friend class shell;
friend class leg;
};
每只海龟还可以计算添加的部件数量,以禁止添加超出允许范围的部件:
virtual bool canAdd(Type t) {
if (t == LEG && nLegs < 4) return true;
else if (t == SHELL && nShell < 1) return true;
else return false;
}
virtualboolcanadd(类型t){
如果(t==LEG&&nLegs<4)返回true;
else如果(t==SHELL&&nShell<1)返回true;
否则返回false;
}
我个人会将约束检查代码移动到专用的工厂类,例如:
class TurtleFactory {
public:
node * newTurtle() const {
node * t = new turtle;
for (int i = 0; i < 4; ++i)
t->addChild(new leg);
t->addChild(new shell);
return t;
}
friend class turtle;
friend class shell;
friend class leg;
};
每只海龟还可以计算添加的部件数量,以禁止添加超出允许范围的部件:
virtual bool canAdd(Type t) {
if (t == LEG && nLegs < 4) return true;
else if (t == SHELL && nShell < 1) return true;
else return false;
}
virtualboolcanadd(类型t){
如果(t==LEG&&nLegs<4)返回true;
else如果(t==SHELL&&nShell<1)返回true;
否则返回false;
}
您的示例可能与源任务不同,但我应该提到:
您不能从leg
继承turtle
,因此只能通过组合将leg
类插入到turtle
类中。这意味着turtle
用户不能直接访问leg
类方法,您应该在turtle
和/或其父类中实现它们。或者,正如在另一个答案中所说,使用接口
我认为完成这门课的最好方法是:
1) 将leg
类中的所有方法设为私有,以禁用直接继承和/或合成
2) 创建一个新的类LegMoving
,它是朋友类,用于腿
,并且知道如何控制腿
leg
将成为LegMoving
类的成员
3) 继承turtle
自LegMoving
我认为这样您就不会违反基本OOP模式。您的示例可能与源任务不同,但我应该提到: 您不能从
leg
继承turtle
,因此只能通过组合将leg
类插入到turtle
类中。这意味着turtle
用户不能直接访问leg
类方法,您应该在turtle
和/或其父类中实现它们。或者,正如在另一个答案中所说,使用接口
我认为完成这门课的最好方法是:
1) 在leg
类privat中设置所有方法
class turtle
: public node
, public legs<turtle,4>
, public shell<turtle> {
public:
turtle()
: legs<turtle,4>({leg(),leg(),leg(),leg()})
, shell<turtle>(false) {
}
void doMoveForward(size_t legIndex) {
// Let the base implementation check the range first
legs<turtle,4>::doMoveForward(legIndex);
// Call the specific behavior
legs_[legIndex]->moveForward(10); // at slow speed
}
};
class clam
: public node
, public shell<clam> {
public:
clam() : shell<clam>(true) {
}
void doOpenShell() {
// Implementation
}
};
class dog
: public node
, public legs<dog,4> {
public:
dog() : legs<dog,4>({leg(),leg(),leg(),leg()}) {
}
void doMoveForward(size_t legIndex) {
// Let the base implementation check the range first
legs<dog,4>::doMoveForward(legIndex);
// Call the specific behavior
legs_[legIndex]->moveForward(100); // at fast speed
}
};