C ++对本地临时对象的引用

时间:2015-11-04 04:17:25

标签: c++

考虑以下模板类

template <typename T>
class A {
public:
    virtual T const& getContent() = 0;
};  

我使用'int *'作为类型'T'派生此类,如下所示

class A1 : public A<int*> {
private:
    int a;
public:
    int* const& getContent() { return &a; }
};

我收到以下警告:'返回对本地临时对象的引用'。

问题:

  1. 在返回引用之前,编译器是否从'&amp; a'隐式实例化了'int * const'类型的本地临时对象?

  2. 我知道A.a确实存在,那么我可以忽略这个警告吗?使用此代码会产生任何不良副作用吗?

  3. 处理这种情况的正确方法是什么?我是否需要使用成员变量'int * a'。这很麻烦。

3 个答案:

答案 0 :(得分:7)

  1. 你不能忽视这个警告。 A.a存在,但这不是问题。您返回的内容不是指向int的指针,而是指向int的指针,即它是双重间接指针。具体而言,在int*内创建了一个指向getContent的临时A.a。返回了对该临时文件的引用,然后销毁了该临时文件。使用getContent的结果将是未定义的行为。
  2. 处理这种情况的惯用方法通常是存储传递const引用的成员。换句话说,拥有一个成员int* a,然后只需在您的函数中返回a。返回const引用是一种公开数据成员的完全功能的常用方法,不允许类的用户改变它,弄乱你的类&#39;不变式。

答案 1 :(得分:0)

这是不正确的:

T const& getContent() = 0;

你可以这样做:

T const getContent() = 0;
int* const getContent() { return &a; }

答案 2 :(得分:0)

首先......

int* const&

与......相同。

int *const&

修改:最初,我错误地说它等同于const int*&。对不起,那是我的错。

并且,对指针的引用更加繁琐&#34;指针本身(至少恕我直言),你不这么认为吗?有一个原因指针和引用永远不会混合(当然,除非它是模板实例化的连续性)...

int const&*

这是不可能的,无效的,最后但并非最不重要的是,疯了。虽然除了通过指针之外没有实用的方法来实现引用,但它们不是对象,因为它们(他们自己)没有{{1}这与他们引用的类型不同,以及他们根本没有地址的事实,至少就N4296的神圣着作而言。

但是...指针对象!表达式sizeof返回类型为&a的rvalue(基本上是一个没有地址的对象)。现在,语句int*将获取该值并将其包含在引用中,因为......

  • 那是函数返回类型所期望的。
  • 类型return &a;的右值的生命周期可以通过在T类型的引用中保留来扩展。但是,您不能使用它来返回对临时右值的引用。

现在,因为所有这些东西意味着你以一种不允许的方式返回对临时右值的引用,你就会被诱惑并陷入未定义的行为。

解决方案?首先,根本不要使用对指针的引用......

const T&

或者,如果你喜欢它,请使用引用,但不是指针......

int const *getContent() { return a; }

现在,问题!

  • *编译器是否隐式实例化了类型为&#39; int * const&#39;的本地临时对象。来自&#39;&amp; a&#39;在返回参考之前?*:是和否。它确实实例化了如上所述的临时(但通常已经优化),但它的类型是int const &getContent() { return *a; } ,而不是int*,尽管后者被隐式地转换为前者。
  • 我知道A.a确实存在,那么我可以忽略这个警告吗?使用此代码会产生任何不良副作用吗?:这取决于您是否会忽略被零除警告。
  • 处理这种情况的正确方法是什么?我是否需要使用成员变量&#39; int * a&#39;代替。这会很麻烦。:你可能会使用&#34;繁琐的&#34;指针或&#34;美丽&#34;参考,见上文。

我希望这能为你带来一些启示!

相关问题