0

Scenario is I have a function which calls parameterized constructor when I want to initialize. So what I want to do is to call constructor of my choice when I want. But it works when I use A() to call default constructor but it does not work with a constructor with the parameter rather I am getting following error.

Error 1 error C2082: redefinition of formal parameter 'tmp' c:\users\adnan\documents\visual studio 2012\projects\project3\project3\source.cpp 12 1 Project3

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;
}
user3461957
  • 163
  • 2
  • 5
  • 14
  • 1
    Calling constructor like `A(tmp);` in a function won't change the id if you want this effect. It will just create a temporary object and vanish instantly. – Mohit Jain Apr 25 '14 at 11:30

3 Answers3

3

In your member function i you're trying to call the c'tor of A like this:

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

In fact A(tmp) declares a variable tmp of type A. Since tmp is already declared as int inside the same scope, the compiler complains.

If you want a variable of type A and initialize it via the A::A(int) c'tor then you need to give a name to that variable. E.g.:

A a(tmp);
1

The line

A(tmp);

doesn't call the constructor, it's declaring an instance of A called "tmp" - it's equivalent to

A tmp;

Since the formal parameter is called "tmp", that's a redefinition.

(Despite what you might expect, A tmp(); is not equivalent to A tmp;- look for "the most vexing parse" to learn more.)

The reason it "works" when you write

A();

is that it creates an anonymous instance (an entirely different one from this) which is immediately thrown away.
In other words, that code doesn't do what you thought it did.

There's no way (in C++03) to explicitly call a constructor except using "placement new", which should not be done unless you know what you're doing.

If you want to delay "initialization" of an object until after it's been constructed, use an initialization function:

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);
    }

};
molbdnilo
  • 64,751
  • 3
  • 43
  • 82
1

There is an ambiguity in the grammar involving expression-statements and declarations:

I have cited the C++ Standard.

That is in this code snippet

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

A(tmp); is considered by the compiler as a declaration equivalent to

A tmp;

To distinguish the constructor call from the declaration you could write

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

In this case ( A )( tmp ) is a constructor call though there is no any sense in this statement.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335