1
#include <string>
#include <iostream>

class a { public: int x;};
class b : public a  {public: int x; } ;

int main()
{
    b bee;
    bee.x = 3;

    a ay = bee;
    std::cout << std::endl << ay.x << std::endl;


}

上面的代码在 clang 3.0 和 g++ 4.5 中编译得很好。但是输出是垃圾(--即,不是三个)。由于编译器似乎不介意,我如何让代码表现出来?

其次,如果有某种方法可以使上述切片/转换正常工作,那么如果我随后执行以下操作会有多糟糕,前提是存在这样做的充分理由:

class c : public a { public: uint64_t x; };

为什么我对这些语义感兴趣。

我想这样做的原因是这个。我有两个类层次结构,其中一个层次结构(父级)在同一层次结构级别上从另一个(子级)聚合对象。我使用自定义容器进行聚合。我想在父类中对容器进行typedef(typedef同名),并在父类的每一层声明同名的容器。

类层次结构旨在在较低级别包含较少的信息(基类持有的信息最少),因此切片在这里非常有意义。

编辑:

好了,这应该可以解决问题了。

class A { int x; }; 
class B : public A {int y;};
class Ap {std::vector<A> entries;};
class Bp : Ap{std::vector<B> entries;};

子类 B 的成员比子类 A 多。但是,我不想为只对类 A 的成员感兴趣的代码提供统一的接口。

4

4 回答 4

2

如果您直接设置b::x. a::xb::x是两个不同的成员,后者隐藏了前者。

您仍然可以使用 访问类型的a::x对象,但根本问题是类型对象的和的值不同步。bstatic_cast<a&>(bee).x = 3a::xb::xb

如果您使用“属性获取器/设置器”抽象访问这两个x成员,那么您可以安排派生类上的设置器也更新基类的成员。或者(也许这更合适?)您可以创建基类的成员protected并直接从派生类中使用它,在从 getter 返回之前根据需要进行切片。

于 2011-03-21T12:59:49.403 回答
1

嗯!它有点复杂,不是吗?

你为什么不使用:

class a
{
virtual void set( int value ) { x = value; }

protected :
    int x;
};

class b : public a 
{
virtual void setA( int value ) { a::x = value; }

或者

virtual void setA( int value ) { b::x = value; }

或者

virtual void setA( int value ) { a::x = value; b::x = value; }

protected:
    int x;
} ;

有两种构建软件设计的方法;一种方法是简单到明显没有缺陷,另一种方法是复杂到没有明显缺陷。第一种方法要困难得多。卡霍尔

于 2011-03-21T13:04:04.593 回答
0

也许尝试这样的事情:

class A { int x; }; 
class B : public A {int y;};
class Ap {
public:
    void Append(A *pa)
    {
        entries.push_back(pa);
    }
    A *GetA(size_t nIndex) 
    {
        return entries.at(nIndex);
    }
private:
    std::vector<*A> entries;
};
class Bp : Ap
{ 
public:
    B *GetB(size_t nIndex) 
    {
        return dynamic_cast<B*>(GetA(nIndex));
    }
};
于 2011-03-21T16:43:20.517 回答
0

根据 Jon 的回答,由于 a::x 和 b::x 是单独的变量,而且由于 b::x 掩盖了 a::x,如果您想获得正确的语义,您需要提供一个复制转换构造函数。以下代码可以解决问题。

#include <string>
#include <iostream>

class b;

class a { 
public: 
    a();
    a(const b & bee);

    int x;
};
class b : public a  {public: int x; } ;


a::a() {}
a::a(const b & bee)
{ 
        x = bee.x;
}  

int main()
{
    b bee;
    bee.x = 3;

    a ay = bee;
    std::cout << std::endl << ay.x << std::endl; 
}
于 2011-03-21T13:41:34.557 回答