在C++中“扩展”结构体

4

我之所以说“扩展”,是因为在谷歌搜索后,我不确定这是否是我要实现的正确名称。

基本上,我想做的是创建一个结构体(只是为了好玩,让我们也包括类),其中有一些空白变量,然后再创建另一个结构体或类,继续父类的工作,填充这些变量。

就像这样:

struct parent{

    int foo;
    int bar;
};

struct daughter : parent{
    foo=1;
    bar=3;
};

struct son : parent {
    foo=10;
    bar=20;

    int foobar;
};

以后,我可能需要进一步分支扩展这棵树:

struct grandson : son {
    foo=50;
    bar=900;
    foobar=10000;
};

如何正确处理这个问题?

编辑:

@所有人: 所以,我可以解释我正在尝试做什么,你们可以用更好的方式反驳,谁知道,也许那些方式更好。然而,首先,我只是好奇我所问的是否可能...

我忘了提到一些东西:

struct parent{
    int foo;
    int bar;
    int foobar;

    int add(int x, int y){
        return x+y;
    };

struct son : parent {
    foo=12;
    bar=13;
    foobar=add(foo,bar);
}

“空变量”的概念让我感到困惑。 - Kerrek SB
1
@AnOptionalName:你知道结构体和结构体实例的区别吗?你在问继承方面的问题,但看起来你只是想要一些结构体类型的变量... - deviantfan
@Kerrek SB:空白变量在我所尝试的事情中非常有用。例如,在游戏中,创建一个带有某些变量初始化的空白怪物类,然后创建一堆具有不同名称/能力等差异的子类。 - AnOptionalName
@deviantfan:这就是为什么我不确定继承是否是正确的词。 - AnOptionalName
有趣的是,有些人会问我一些非常新手的问题,展现出糟糕的编程风格,但在制作游戏的过程中却能写出最棒的作品! - hookenz
显示剩余3条评论
6个回答

7

我认为你可以使用构造函数来初始化值,像这样:

struct daughter : public parent {
   daughter() {
      foo=1;
      bar=3;
   }
};

(顺便说一下,我知道'public'关键字并不是必须的,我只是喜欢保持我的意图明确;否则后来我总会想我是否忘记指定)


@AnOptionalName 还要注意 struct son : public /* <<<<<*/ parent; - πάντα ῥεῖ
2
@Jeremy Friesner 看起来提问者在C++方面经验不是很丰富。为了让这些人从所有可能性中学到“最好的”东西,我建议您在构造函数中引入初始化列表而不仅仅是在构造函数体中分配它们。 - Doonyx
哈哈,好的。现在是夏天,我得完成那个C++课程了。谢谢。 - AnOptionalName
@AnOptionalName:这取决于你所说的“work”的含义... struct foo; “声明”了一个名为foo的结构体。如果你进行这样的声明,你可以对struct进行有限的操作 - 例如声明一个带有foo*foo&参数的函数 - 即使在编译器看到foo定义之前(定义是struct foo { ... };代码)。struct foo;不会创建任何变量。 - Tony Delroy
@JeremyFriesner 没错。我的意思是我们必须在基类构造函数中引入它们。抱歉给你带来了误导。最终,我只是想提一下类似这样的东西,struct parent{ private: int foo; int bar; public: parent(int _foo, int _bar):foo(_foo), bar(_bar){} };struct daughter : parent{ public: daughter(int _foo, int _bar): parent(_foo, _bar){} };然而,现在其他答案中也有这些内容。 - Doonyx
显示剩余3条评论

3

除了初始类值之外,您的父级子级本质上是相同类型。 同样适用于孙子儿子

为什么不使用构造函数来完成这项任务?

struct parent
{
    parent () : foo(), bar() {}
    parent (int the_foo, int the_bar) 
      : foo(the_foo), bar(the_bar) {}
    int foo;
    int bar;
};

struct son : public parent
{
    son () : parent(10,20), foobar(foo+bar) {}
    son (int the_foobar) 
      : parent(10,20), foobar(the_foobar) {}
    int foobar;
}

int main ()
{
  parent p;
  parent daughter(1,3);
  son s;
  son grandson(10000);
}

0
在C ++中,结构体被视为类,其中所有成员默认公共。因此,您可以获得所需的行为。但是,您需要使用构造函数初始化变量,不能直接像您编写的那样执行。所以这个:
struct parent{
int foo;
int bar;
int foobar;

int add(int x, int y){
    return x+y;
};

struct son : parent {
foo=12;
bar=13;
foobar=add(foo,bar);

应该写成

struct parent
{
  int foo;
  int bar;
  int foobar;

  int add(int x, int y){
    return x+y;
  };
};

struct son : parent 
{
  son()
  {
    foo = 12;
    bar = 13;
    foobar = add(foo,bar);
    // or just: foobar = foo+bar;
  }
};

但在这种情况下,儿子和父亲实际上是相同结构的实例化。这是相当愚蠢的。如果你要添加更多字段到儿子那里,因为继承就是为此而来的。在你的情况下,你的父亲和儿子是完全相同的,只是持有不同的状态。另一方面,如果儿子需要持有其他数据,则需要继承。

另外,如果您要通过添加方法将structs视为类,为什么不直接将它们作为类呢。


我的个人观点是使用结构体进行数据存储和非常小/简单的方法。 - AnOptionalName
由你决定如何处理。但是如果有方法,我通常会将它们制作成类。有时候,如果只有一个简单的构造函数,我会将它们保留为结构体。但除此之外,我会将它们制作成类(即使它们实际上已经是类)。 - hookenz

0

在这种情况下,我不认为继承是必要的。如果您只想获取具有特定值的parent实例,则一个简单的函数可能就足够了:

parent get_daughter() {
    // note that this syntax requires c++11
    // in earlier standards you may want to add a constructor to the class
    return {1, 3};
};

son引入了一个新成员,因此继承是合适的。


即使您是正确的,问答的价值在于其他人可以找到相同问题的答案。这不是问题的答案。 - Seph Reed
@SephReed 不仅回答被问到的问题,还要解决提问者试图解决的问题是很有用的。如果这个问题促使 OP 提出这个问题,那么其他遇到同样问题的人在搜索相同问题时也可能会来到这里。这就是问答的价值所在。另请参阅:http://xyproblem.info/ - eerorika

0

我认为像Java和C#这样的语言可能有一些关于本地对象初始化的工资定义。但是,对我来说,C++有最好的解释成员变量(非静态)初始化的方式。只需在构造函数内部完成它们。非常清晰、直观且不容易出错。


-2

  • 不要使用struct进行继承:应该使用class。这会削弱继承层次结构中的保护级别,因为结构体成员的默认隐私级别是public。阅读C++代码的C程序员会认为这些结构体没有被继承,也没有方法等。

  • 将所有成员设置为私有(如果未被继承类修改)或受保护(如果被继承类修改),以防止类的实例化者意外修改。
  • 如果希望其他代码可以实例化这些类,则需要将构造函数设置为public
  • class parent{
    
    protected:
        int foo;
        int bar;
    public:
        parent() {
            foo = 0;
            bar = 0;
        }
    };
    
    class daughter : parent{
    private:
    public:
        daughter() {
            foo=1;
            bar=3; 
        }
    };
    
    class son : parent {
    private:
        int foobar;
    public:
        son () {
            foo=10;
            bar=20;
            foobar = 0;
        }
    };
    

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接