3

我正在使用一个庞大的 C++ 代码库。

我想引入一个新的子类,并在各种不同的上下文中使用它,但是我受过 Java 训练的头脑在 C++ 中遇到了麻烦。

我希望尽量减少代码更改。所以,我感兴趣的主要类(BAR下面)有一个成员变量 class FOO。我希望创建一个FOO被调用的子类FOOSUBCLASS。在java中这是微不足道的。默认情况下,对象是通过引用存储的。此代码不这样做(如下所示)我可以在不更改接口(并且不引入引用)的情况下按摩此代码并且仍然使我的应用程序工作吗?

class FOO {
};

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

class BAR {
public:
    BAR(const FOO foo) { _foo = foo;}
private:
    FOO _foo;
};

下面,是我的主要内容:

FOOSUBCLASS fsc(1);
BAR b(fsc);

但这不能在 VS2005 中编译。它说:

'type cast' : 从 'FOOSUBCLASS *' 到 'const FOO &' 的转换存在,但无法访问

如果我将明显的其他构造函数添加到BAR

BAR(const FOOSUBCLASS foo) { _foo = foo;}

我对 C++ 的理解是,它将数据复制FOOSUBCLASS到 class 的对象中FOO。(使用赋值运算符,或它的类覆盖版本)但在我的情况下,我有额外的成员变量FOOSUBCLASS(和一些被覆盖的成员函数)所以我只是不希望它这样做。我希望我的成员变量在某些情况下和其他情况下_foo真正具有类型。这甚至可能吗?FOOSUBCLASSFOO

谢谢你的想法。

4

4 回答 4

2

公开基类

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

另外,请注意在BAR构造函数中切片

分配给指针/引用以避免这种情况:

class FOO
{
};

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

class BAR
{
public:
    BAR(const FOO& foo) : _foo(foo)
    {
    }
private:
    FOO& _foo;
};

注意:我在构造函数主体中使用了初始化列表语法而不是赋值。

于 2012-10-11T23:15:31.177 回答
2

你不能按照你现在写的方式去做,对不起。这称为“切片”,有关它的更多信息可以在这里找到:什么是对象切片?

如果您希望您的_foo成员是多态的,则需要使用指针或引用。当你做这样的事情时,当然要注意生命周期管理。

于 2012-10-11T23:17:58.047 回答
1

首先在 C++ 类中默认使用private从它们的基类继承,这意味着这FOOSUBCLASS是一个FOO但转换是内部的,您无法访问。所以首先转换class FOOSUBCLASS : FOOclass FOOSUBCLASS : public FOO,第二个是在 Java 中,每个 this 都是参考,所以你可以说

FOOSUBCLASS fs;
FOO f = fs;

但是在 C++ 中,我们有引用和非引用,并且使用FOO f创建一个实际上是对象的非引用,因此FOO f = fs只复制FOO一部分fsf并且不会导致对 a 的FOO引用FOOSUBCLASS来实现这一点,您应该使用指针或引用或智能指针。例如你可以说:

FOOSUBCLASS* fs = new FOOSUBCLASS;
FOO* f = fs;   // Use pointer is OK
FOO& rf = fs;  // A reference of fs as a FOO
std::auto_ptr<FOO> spf( fs );  // OK, but for this destructor must be virtual
于 2012-10-11T23:31:44.450 回答
0

对于用户 sehe,请考虑将引用而不是按值传递给 BAR 的构造函数。

class BAR { public: BAR(const FOO& foo) { _foo = foo;} private: const FOO& _foo; };

于 2012-10-11T23:26:50.403 回答