说我有一个父类class Parent
和两种类型的孩子class Son
和class Daughter
。 Son
和Daughter
共有的属性
在Parent
现在我定义一个Son
实例和一个Daughter
实例。他们有不同
方法,可以做不同的事情,但Son
做某事,Daughter
等待(和相互)。 Son
或Daughter
的操作都是。Parent
或static
重新定义Daughter
中应考虑的一些属性
两个孩子。
实现这一目标的第一个想法是将这些属性设置为Son
,以便如果
Son
更改内容,也会影响Daughter
。但我的问题是
它会影响class Parent{
public:
/*define some constructors and parent stuff*/
void set_family_name(std::string f){ family_name = f; }
protected:
std::string family_name;
}
class Son : public Parent{
public:
/*define some constructors and son stuff*/
}
class Daughter : public Parent{
public:
/*define some constructors and daughter stuff*/
}
int main(){
Son JohnSmith(/*some attributes*/);
Daughter AnnaSmith(/*some attributes*/);
Son BobWeston(/*some attributes*/);
JohnSmith.set_family_name("Smith"); /*should also affect AnnaSmith but not BobWeston*/
}
和class FamilyAttribute
的所有实例,我只想影响
那些在同一个“家庭”中的人。
这是一个公开我的问题的伪代码:
Parent
有没有办法连接两个子实例,以便在更改时 父参数反映在另一个上,但不是全部反映?
我想到的第一个解决方案是设置其他类,
class FamilyAttribute{
public:
/*define some constructors and family stuff*/
void set_family_name(std::string f){ family_name = f; }
private:
std::string family_name;
}
class Parent{
public:
/*define some constructors and parent stuff*/
void set_family_name(std::string f){ attribute->set_family_name(f); }
protected:
FamilyAttribute* attribute;
}
中将引用的Parent
。类似的东西:
apache-drill
但是这会让我重写所有的方法,这也会增加
方法调用次数。它似乎也很奇怪,因为现在只有HBase
对多态性有用(我需要)。
有更简洁的方法吗?
答案 0 :(得分:2)
C ++支持多种共享变量的方法,但它们都不允许您逐个实例地控制共享。语言不知道“家庭”的概念,所以你必须自己构建它。
在FamilyAttribute
中引入常见Parent
的解决方案是正确的。您可能想要调整实现,例如通过将类重命名为Family
,或用引用替换指针,但方向是绝对正确的:您需要定义一个单独的类来表示共享数据,并根据需要配置共享族的实例。
请注意,源自Son
的{{1}}和Daughter
的实施很可能存在缺陷,因为公开推导表明Parent
或Son
可能是用作Daughter
(请参阅Liskov Substitution Principle)。为了捕捉Parent
和Son
之间的共同点而不考虑其性别,您应该将Daughter
类重命名为Parent
。
答案 1 :(得分:2)
有没有办法连接两个子实例,这样当一个更改一个父参数时,它会反映在另一个实例上,但不会全部反映在所有实例中?
不是自动在类型系统中,没有。
没有办法将类型的某些实例连接到类型的其他任意实例,而不使用类似指针来连接它们。
看起来你想要建模的是人,有两种类型的具体子类,儿子和女儿(或男人和女人),所以儿子是一个人,女儿是一个人。
系列名称是一个属性,应该由HAS-A关系建模,以便Person HAS-A指向FamilyName对象的指针,以及多个Person对象可以引用相同的FamilyName。 (shared_ptr
将是对其进行建模的最佳方式,以便正确管理所有权)。
但这会让我重写所有方法,这也会增加方法调用次数。
这是不可能的,因为你没有显示任何方法,所以不可能知道它为什么会重写它们。
它似乎也很奇怪,因为现在Parent只对多态(我需要)有用。
要么我不明白你的意思,要么我不明白为什么这很奇怪或为什么这是一个问题。如果你需要多态性,为什么有一个提供多态接口的基类会很奇怪?
答案 2 :(得分:0)
您可以将以下私有成员引入基类:
static std::map<FamilyId, FamilyAttributes> FamilyPropertyMap;
FamilyId将是您要为您的家庭排序的唯一标识符的typedef;也许只是一个名字的字符串,也许是别的东西。 FamilyAttributes将是一个存储公共数据的对象,所有具有相同“族”的派生对象都希望具有共享访问权限。存储所有变量的结构,您希望公共访问,最初可能就足够了。
然后,您可以将以下public或protected方法添加到基类:
FamilyAttributes& getMyFamiliesAttributes(){return FamilyPropertyMap[family_name];}
我假设你在这里使用字符串family_name作为地图的键。 这样,您可以将所有派生对象的访问权限限制为其特定“族”的数据。如果家庭以外的人应该能够访问家庭财产,则将该方法设为公共,如果只有派生对象应该能够在内部处理数据,则使其受到保护。
静态地图可能不是最优雅的或OO解决方案,但它有一个优点,即您不必处理指针。确保正确初始化family_name字符串或在访问映射时检查空字符串。