4

我想像这样this作为参数传递给成员变量:

template<class T>
struct fun
{
    fun(T* pointer) : memberPointer(pointer)
    {
    }
    T* memberPointer;
};

struct gun
{
    gun() : member(this)
    {
    }
    fun<gun> member;
};

在 Visual Studio 中,我有下一个警告:warning C4355: 'this' : used in base member initializer list

你能解释一下为什么这样做是错误的吗?我只是将指针存储在成员构造函数中,以便以后使用它来gun调用fun.

4

4 回答 4

5

潜在的问题是this指向尚未完全构造的对象。例如,如果你有这个:

template<class T>
struct fun
{
    fun(T* pointer) : memberPointer(pointer)
    {
        memberPointer->callMethod(); //this is 2nd to execute
    }

    T* memberPointer;
};

struct gun
{
    gun() : member(this) //this is 1st to execute
    {
       ptr = new char(); // this is 4rd to execute unless earlier UB prevents execution
    }
    void callMethod()
    {
       printf("%s", ptr); //this is 3rd to execute, you get UB here
    }
   fun<gun> member;
   char* ptr;
};

您会遇到未定义的行为,因为您将传递一个指向未完全构造的对象的指针,其中只应传递指向完全构造的对象的指针。我特意用 UB 编写了一些蹩脚的代码来更有说服力,在现实生活中你不一定会遇到 UB 问题,有时所有对象都会处于有效状态,所以你会得到一些非常微妙的初始化顺序错误。

那不是你的情况。您的情况很好-您不在乎对象尚未完全构造。但是,在更改代码时应该小心,以免陷入上述情况。

于 2013-04-04T07:13:24.600 回答
1

这只是一个警告。如果您要this在 fun 构造函数中遵循,那么您将访问一个未初始化的对象。但你不是,你只是存储指针,所以你可以忽略警告。如果要关闭警告,请将其添加到代码顶部

#pragma warning (disable: 4355)
于 2013-04-04T07:14:26.627 回答
0

这并不是完全错误的,但是当您传递指针时,您的枪对象可能尚未完全构建。因此,您可能会调用基类中依赖于对象的完整构造的方法。

于 2013-04-04T07:14:45.050 回答
0

您想要的是实现静态多态性,最好通过奇怪的重复模板模式 (CRTP)来处理。就您而言,您几乎就在那里:

template<class Base>
struct fun : public Base
{
    void foo()
    {
        // call gun function
        Base::bar();
    }
};

struct gun : public fun<gun>
{
    void bar()
    {
        /*...*/
    }
};
于 2013-04-04T07:20:00.067 回答