コンストラクション関数パラメータとして暗黙的オブジェクトを作成/関数表現を使用した明示的なタイプ変換

4064 ワード

コンストラクション関数を見てパラメータとして暗黙的なオブジェクトを作成する例
#include
using namespace std;

class A
{
	int a;
	int b;
public:
	A() { cout << "    " << endl; };
	A(int, int) { cout << "int    " << endl; };
	A(const A &) { cout << "      " << endl; };
	void operator()(int a, int b) { cout << "  ()     " << endl; }
	void sum() { cout << "Sum     " << endl; }
};

void set(A visit) {
	visit(1, 2);
}

int main()
{
	A a = A();
	set( a );
	cout << endl;

	A *b = new A(1,2);  
	A *c = new A;
	A *d = new A();
	b->sum();
	c->sum();
	d->sum();
        delete b, c, d;

	cout << endl;

	set(A());

	return 0;
}

 set_1( A()); これはコンストラクション関数を呼び出して一時オブジェクトを作成することです
Yes. The manner in which you are constructing the object in the line:
set(A()); is called functional notation type conversion. This is specified in the section on constructors.
A functional notation type conversion can be used to create new objects of its type. [Note: The syntax looks like an explicit call of the constructor. —end note]
An object created in this way is unnamed.
set(A();機能シンボルタイプ変換と呼ばれます.コンストラクション関数のセクションで指定します.
機能表現タイプ変換は、そのタイプの新しいオブジェクトを作成するために使用できます.[注:構文は、コンストラクション関数の明示的な呼び出しのように見えます.-文末脚注]
このようにして作成されたオブジェクトは名前が付いていません.
「C++primer plus」のP 709ページには、コンストラクション関数呼び出しによって作成された匿名オブジェクトとして解釈される同じ内容が表示されます.
 
A constructor is used to initialize objects of its class type. Because constructors do not have names, they are never found during name lookup; however an explicit type conversion using the functional notation will cause a constructor to be called to initialize an object. [ Note: The syntax looks like an explicit call of the constructor. — end note ]
complex zz = complex(1,2.3); cprint( complex(7.8,1.2) );
コンストラクション関数は、クラスタイプのオブジェクトを初期化するために使用されます.コンストラクション関数には名前がないため、名前検索中にそれらは見つかりません.ただし、関数表現の明示的なタイプ変換を使用すると、コンストラクション関数を呼び出してオブジェクトを初期化します.[注:構文は、コンストラクション関数の明示的な呼び出しのように見えます.]
complex zz = complex(1,2.3); cprint( complex(7.8,1.2) );このようにして作成されたオブジェクトは名前が付いていません.
 
関数表現を使用した明示的なタイプ変換:
If the initializer is a parenthesized single expression, the type conversion expression is equivalent (in definedness, and if defined in meaning) to the corresponding cast expression ([expr.cast]). If the type is (possibly cv-qualified) void and the initializer is (), the expression is a prvalue of the specified type that performs no initialization. Otherwise, the expression is a prvalue of the specified type whose result object is direct-initialized ([dcl.init]) with the initializer. For an expression of the form T(), T shall not be an array type.
初期値設定項目がかっこ付きの単一式の場合、タイプ変換式は、対応する強制変換式([expr.cast])と等価です(定義では、意味的に定義されている場合).タイプが(CV制限子である可能性がある場合)voidであり、初期化プログラムは()の場合、式は、初期化を実行しない指定されたタイプの純右値です.それ以外の場合、式は指定されたタイプの純右値であり、その結果、オブジェクトは初期化プログラムを使用して直接初期化されます([dcl.init]).T()形式の式では、Tは配列タイプではありません.
CV-qualifiersには、const-qualifier(const限定子)、volatile-qualifier(volatile限定子)、const-volatile-qualifier(const-volatile限定子)の3種類があります.glvalue( ) = lvalue ( )+ xvalue( , ) rvalue ( ) = prvalue( ) + xvalue
 
 
 
ソース:https://stackoverflow.com/questions/53422994/does-calling-the-constructor-directly-outside-the-class-implicitly-create-an-obj/53423948#53423948
https://timsong-cpp.github.io/cppwp/n4618/expr.type.conv
P.Wさんの回答に感謝します.
 
パラメータと戻り値の例として他のオブジェクトを見てリラックスします.
int main()
{
    PriorityQueue pq1();
    pq1.insert(3); // doesn't compile

    PriorityQueue pq2 = PriorityQueue();
    pq2.insert(3); // compiles
}

PriorityQueue pq 1();関数体として扱われ、PriorityQueueは値タイプを返し、pq 1は関数名である. 
#include 
using namespace std;
class human
{
  public:
  human(){ human_num++;};
  static int human_num;
  ~human()
  {
     human_num--;
     print();
  }
  void print()
  {
    cout <