1

我有一个 C++ 切片问题。我是 C++ 的新手,所以可能太笨了,无法意识到这无法完成....我尝试了各种解决方法,我目前的最佳方法如下所示。(我需要做这样的事情来避免在非常大的遗留代码库中更改大量接口。无论如何不要声称这是优雅的风格!!)

编译时遇到麻烦。这个想法合理吗?还是整个方法注定要失败?引用的构造函数似乎是问题所在。我已经阅读了 Stroustrup 的“C++ Programming Language”(或者至少我认为是相关部分),但它没有帮助。

class FOO {};

class FOOSUBCLASS : public FOO {
public:
    FOOSUBCLASS(const int id = 0) : _id(id) {}
private:
    int _id;
};

class BAR {
public:
    BAR(const FOO foo) : _foo(foo), _realFoo(&_foo) { }

BAR(const FOOSUBCLASS foosc) : _foosc(foosc), _realFoo(&_foosc) {} 
private:
    FOO _foo;
    FOOSUBCLASS _foosc;
    FOO& _realFoo;
};

编译器不喜欢我的_realFoo(&_foo)行。我希望对_foo, 的引用只是类中成员变量的引用。这在 C++ 中是不可能的吗?

这是来自 VS2005 的具体错误:

'initializing' : cannot convert from 'FOO *' to 'FOO &'
4

2 回答 2

2

_foo是一个FOO&
&_foo是一个FOO*
编译器cannot convert from 'FOO *' to 'FOO &'
你想要的是..., _realFoo(_foo)

不相关:你可能真正想要的是一个std::unique_ptr<FOO>成员。这将更小,更不容易出错。

您现在拥有的结构包含 的完整且完整的实例FOO、 的完整且完整的实例FOOSUBCLASS和引用。至少把这两个东西放在一个联合体中,所以 的大小只比最大的导数大一点。那可能会使用与. 不幸的是,s 是 C 和 C++ 中常见的错误来源。FOOBARFOOunique_ptr<FOO>union

另一个问题是,如果有人过来写

class FOOSOMETHINGELSE : public FOO {
   int buffer[1024];
};

然后你必须去找到这个BAR类,改变它,让它变得更大,然后重新编译你BAR在任何地方都使用的所有代码。然而,如果您使用 a unique_ptr<FOO>,那么您将不必更改BAR或重新编译任何内容。所以出错的机会更小。

于 2012-10-11T23:57:22.873 回答
1

这里有几个问题。您正确地将其中之一识别为切片,但切片不会导致编译时错误(这就是让它如此可怕的原因......)。Mooing Duck 的答案应该可以解决您遇到的编译问题,但切片问题仍然存在。假设你有

FOO *x = new FOOSUBCLASS;
BAR y(*x);

这将导致切片,因为将调用以下构造函数:

BAR(const FOO foo) : _foo(foo), _realFoo(&_foo) { }

它按值获取参数,这意味着将发生从派生到基的复制。

当您尝试将派生类类型的对象分配给基类对象时,就会发生切片,例如,通过将派生类传递给一个函数,该函数按值获取基类,就像您在此处所做的那样。基本上,派生类对象的任何数据成员都会默默地被“切掉”,因为根本没有任何空间可以将它们放入一块仅足以容纳基类对象的内存中。当您需要使用可能实际上是派生类的对象时,您必须使用引用我们的指针(或智能指针,如shared_ptror unique_ptr)。

我很确定您在这里要做的就是让一个BAR对象引用一个对象,该对象要么是一个对象,要么是FOO从它派生的东西——对吗?在这种情况下(并假设对象的生命周期FOO超过了对象的生命周期BAR),您只需要:

class BAR {
public:
    explicit BAR(FOO& foo) : _foo(foo) {}

private:
    FOO& _foo;
};
于 2012-10-12T00:26:27.893 回答