Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling constructor with member as argument parsed as variable definition

I observed peculiar behavior in g++4.6.3. When creating a temporary by calling class constructor File(arg) the compiler chooses to ignore the existence of arg and parse the expression as File arg;

  • Why is the member name ignored?
  • What does the standard say?
  • How to avoid it? (Without using new {} syntax)
  • Is there a related compiler warning? (I could use an arbitrary string arg and it would still work quietly)

Code:

#include <iostream>

class File {
public:
    explicit File(int val) : m_val(val) { std::cout<<"As desired"<< std::endl; }
    File() : m_val(10) { std::cout<< "???"<< std::endl;}

private:
    int m_val;
};

class Test {
public:
    void RunTest1() { File(m_test_val); }
    void RunTest2() { File(this->m_test_val); }
    void RunTest3() { File(fhddfkjdh); std::cout<< "Oops undetected typo"<< std::endl; }
private:
    int m_test_val;
};

int main()
{
    Test t;
    t.RunTest1();
    t.RunTest2();
    t.RunTest3();
    return 0;
}

Output:

$ ???
$ As desired
$ Oops undetected typo
like image 676
Xyand Avatar asked Oct 15 '12 10:10

Xyand


People also ask

Can we call constructor from method in C++?

A constructor can call methods, yes. A method can only call a constructor in the same way anything else can: by creating a new instance.

Can constructor be called directly?

No, you cannot call a constructor from a method. The only place from which you can invoke constructors using “this()” or, “super()” is the first line of another constructor.

Can constructor be const in c++?

Constructors may be declared as inline , explicit , friend , or constexpr . A constructor can initialize an object that has been declared as const , volatile or const volatile . The object becomes const after the constructor completes.

Can we call constructor without creating object in C++?

Yes, it is possible to call special member functions explicitly by the programmer. Example: CPP.


1 Answers

The compiler treats the line:

File(m_test_val);

as

File m_test_val;

so you're actually creating a named object called m_test_val using the default constructor. Same goes for File(fhddfkjdh).

The solution is File(this->m_test_val) - this tells the compiler that you want to use the member to create create a named object. Another would be to name the object - File x(m_test_val).

like image 67
Luchian Grigore Avatar answered Oct 18 '22 21:10

Luchian Grigore