【问题标题】:Error C2082: redefinition of formal parameter 'tmp'错误 C2082:重新定义形式参数“tmp”
【发布时间】:2014-04-25 11:27:21
【问题描述】:

场景是我有一个函数,它在我想初始化时调用参数化构造函数。所以我想做的是在我想要的时候调用我选择的构造函数。但是当我使用A() 调用默认构造函数时它可以工作,但它不适用于带有参数的构造函数,而是我收到以下错误。

错误1 错误C2082:重新定义形参 'tmp' c:\users\adnan\documents\visual studio 2012\projects\project3\project3\source.cpp 12 1 项目3

class A
{
public:
    int id;
    void i(int tmp)
    {
        A(tmp);
    }

    A()
    {
        cout<<"default const"<<endl;
    }

    A(int id)
    {
        this->id = id;
    }

};

int main()
{

    A obj[2];

    for(int i=0;i<2;i++)
    {
        obj[i].i(i*2);
    }

    cout<<"obj[0].id = "<<obj[0].id;
    cout<<endl;
    cout<<"obj[1].id = "<<obj[1].id;
    cout<<endl;


    system("pause");
    return 0;
}

【问题讨论】:

  • 如果你想要这个效果,在函数中调用像A(tmp);这样的构造函数不会改变id。它只会创建一个临时对象并立即消失。

标签: c++ debugging constructor redefinition


【解决方案1】:

在您的成员函数 i 中,您尝试像这样调用 A 的 c'tor:

void i(int tmp)
{
    A(tmp);
}

实际上A(tmp) 声明了一个A 类型的变量tmp。由于tmp 已在同一范围内声明为int,因此编译器会报错。

如果您想要一个A 类型的变量并通过A::A(int) c'tor 对其进行初始化,那么您需要为该变量命名。例如:

A a(tmp);

【讨论】:

    【解决方案2】:

    线

    A(tmp);
    

    不调用构造函数,它声明了一个名为“tmp”的A 实例——它相当于

    A tmp;
    

    由于形参被称为“tmp”,这是一个重新定义。

    (尽管您可能会想到,A tmp();等同于 A tmp;- 查找“最令人头疼的解析”以了解更多信息。)

    当你写作时它“起作用”的原因

    A();
    

    是它创建了一个匿名实例(与this 完全不同的实例),该实例立即被丢弃。
    换句话说,该代码并没有按照您的想法执行。

    除了使用“placement new”之外,没有办法(在 C++03 中)显式调用构造函数,除非您知道自己在做什么,否则不应该这样做。

    如果您想将对象的“初始化”延迟到构造完成后,请使用初始化函数:

    class A
    {
    public:
        int id;
        void init(int tmp)
        {
            id = tmp;
        }
    
        A()
        {
            cout<<"default const"<<endl;
            init(0); // Avoid accidental undefined behaviour.
        }
    
        A(int id)
        {
            init(id);
        }
    
    };
    

    【讨论】:

      【解决方案3】:

      涉及表达式语句的语法存在歧义 和声明:

      我引用了 C++ 标准。

      在这段代码中就是sn-p

      void i(int tmp)
      {
          A(tmp);
      }
      

      A(tmp);被编译器视为等同于

      的声明
      A tmp;
      

      为了区分构造函数调用和你可以编写的声明

      void i(int tmp)
      {
          ( A )( tmp );
      }
      

      在这种情况下, ( A )( tmp ) 是一个构造函数调用,尽管该语句没有任何意义。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-11-10
        • 2014-08-22
        相关资源
        最近更新 更多