自定義一個類:
class A
{
private:
int value;
public:
A(int n)
{
value=https://bbs.csdn.net/topics/n;
}
}
int main()
{
A a=10;//這種初始化方式是什么原理?
}
感謝!
uj5u.com熱心網友回復:
這屬于賦值,或者叫拷貝建構式。編譯器提供默認的拷貝建構式。
uj5u.com熱心網友回復:
不是拷貝構造。是直接呼叫它的帶參建構式。uj5u.com熱心網友回復:
沒有copy elision優化時,先隱式呼叫A(int),再呼叫A(const A&)有copy elision優化時,只隱式呼叫A(int)
uj5u.com熱心網友回復:
凡在物件從同型別的另一物件(以直接初始化或復制初始化)初始化時,呼叫復制建構式(除非多載決議選擇了更好的匹配或其呼叫被消除),情況包括
初始化:T a = b; 或 T a(b);,其中 b 型別為 T;
函式實參傳遞:f(a);,其中 a 型別為 T 而 f 為 Ret f(T t);
函式回傳:在如 T f() 這樣的函式內部的 return a;,其中 a 型別為 T,它沒有移動建構式
記住是同型別
uj5u.com熱心網友回復:

https://bbs.csdn.net/topics/397142613
-fno-elide-constructors
uj5u.com熱心網友回復:
大概明白您的意思了,是不是就是沒有優化的時候1這個引數先用來隱式構造一個A類物件(臨時物件),再通過拷貝構造拷貝給a,有優化的話就是直接隱式呼叫建構式直接構造a,我這樣理解對嘛?uj5u.com熱心網友回復:
#include <iostream>
class A
{
public:
A(int n) {
value = n;
}
friend std::ostream & operator << (std::ostream &out, const A& a) {
out << a.value;
return out;
}
private:
int value;
};
int main(int argc, char *argv[])
{
A a = 10;
std::cout << a << std::endl;
return 0;
}
1. 先試驗explicit constructor
#include <iostream>
class A
{
public:
explicit A(int n) { // Notice here!!!
value = n;
}
friend std::ostream & operator << (std::ostream &out, const A& a) {
out << a.value;
return out;
}
private:
int value;
};
int main(int argc, char *argv[])
{
A a = 10;
std::cout << a << std::endl;
return 0;
}
// Compiler complained
// error: conversion from ‘int’ to non-scalar type ‘A’ requested
// A a = 10;
說明至少存在隱式轉化
2. 再試驗,禁掉copy constructor
#include <iostream>
class A
{
public:
A(int n) {
value = n;
}
A(const A&) = delete; // Notice here!!!
friend std::ostream & operator << (std::ostream &out, const A& a) {
out << a.value;
return out;
}
private:
int value;
};
int main(int argc, char *argv[])
{
A a = 10;
std::cout << a << std::endl;
return 0;
}
// Compiler complained
// main.cpp: In function ‘int main(int, char**)’:
// main.cpp:23:11: error: use of deleted function ‘A::A(const A&)’
// A a = 10;
// ^~
// main.cpp:10:5: note: declared here
// A(const A&) = delete;
說明使用到了copy constructor
由此,A a = 10,compiler會替你產生這樣的代碼:
A temp(10); // int convert to class A
A a(temp); // copy constructor
3. 禁用copy assignment construct是沒有用的,因為初始化時用的是copy constructor
#include <iostream>
class A
{
public:
A(int n) {
value = n;
}
A& operator=(const A&) = delete; // Notice here!!!
friend std::ostream & operator << (std::ostream &out, const A& a) {
out << a.value;
return out;
}
private:
int value;
};
int main(int argc, char *argv[])
{
A a = 10;
A ano_a(20);
ano_a = a;
std::cout << a << std::endl;
return 0;
}
// compiler complained
// main.cpp: In function ‘int main(int, char**)’:
// main.cpp:24:13: error: use of deleted function ‘A& A::operator=(const A&)’
// ano_a = a;
// ^
// main.cpp:10:8: note: declared here
// A& operator=(const A&) = delete;
// ^~~~~~~~
uj5u.com熱心網友回復:
論中文編程的重要性uj5u.com熱心網友回復:
說白了A a(10)
A a=10
這倆對于編譯器有區別嗎?
uj5u.com熱心網友回復:
說白了
A a(10)
A a=10
這倆對于編譯器有區別嗎?
uj5u.com熱心網友回復:
在C++ Primer(5th Edition) 7.5.4章節Implicit class-type conversions中,介紹了一點背后的原理。如果constructor只有一個parameter,那么相應的該class會隱式地定義一種、由parameter's type到class' type的轉換,
并且把這種constructor起了個名字叫converting constructor。
explicit關鍵字可以抑制這種隱式轉換,并且只對converting constructor管用,對有多個parameter的constructor無效。
使用explicit關鍵字后,雖然無法隱式轉換了,但依舊可以使用顯示轉換來強制執行
A a = static_case<A>(10);
uj5u.com熱心網友回復:
#include <iostream>
class A
{
public:
A(int n) {
value = n;
}
friend std::ostream & operator << (std::ostream &out, const A& a) {
out << a.value;
return out;
}
private:
int value;
};
int main(int argc, char *argv[])
{
A a = 10;
std::cout << a << std::endl;
return 0;
}
1. 先試驗explicit constructor
#include <iostream>
class A
{
public:
explicit A(int n) { // Notice here!!!
value = n;
}
friend std::ostream & operator << (std::ostream &out, const A& a) {
out << a.value;
return out;
}
private:
int value;
};
int main(int argc, char *argv[])
{
A a = 10;
std::cout << a << std::endl;
return 0;
}
// Compiler complained
// error: conversion from ‘int’ to non-scalar type ‘A’ requested
// A a = 10;
說明至少存在隱式轉化
2. 再試驗,禁掉copy constructor
#include <iostream>
class A
{
public:
A(int n) {
value = n;
}
A(const A&) = delete; // Notice here!!!
friend std::ostream & operator << (std::ostream &out, const A& a) {
out << a.value;
return out;
}
private:
int value;
};
int main(int argc, char *argv[])
{
A a = 10;
std::cout << a << std::endl;
return 0;
}
// Compiler complained
// main.cpp: In function ‘int main(int, char**)’:
// main.cpp:23:11: error: use of deleted function ‘A::A(const A&)’
// A a = 10;
// ^~
// main.cpp:10:5: note: declared here
// A(const A&) = delete;
說明使用到了copy constructor
由此,A a = 10,compiler會替你產生這樣的代碼:
A temp(10); // int convert to class A
A a(temp); // copy constructor
3. 禁用copy assignment construct是沒有用的,因為初始化時用的是copy constructor
#include <iostream>
class A
{
public:
A(int n) {
value = n;
}
A& operator=(const A&) = delete; // Notice here!!!
friend std::ostream & operator << (std::ostream &out, const A& a) {
out << a.value;
return out;
}
private:
int value;
};
int main(int argc, char *argv[])
{
A a = 10;
A ano_a(20);
ano_a = a;
std::cout << a << std::endl;
return 0;
}
// compiler complained
// main.cpp: In function ‘int main(int, char**)’:
// main.cpp:24:13: error: use of deleted function ‘A& A::operator=(const A&)’
// ano_a = a;
// ^
// main.cpp:10:8: note: declared here
// A& operator=(const A&) = delete;
// ^~~~~~~~
大概是這樣,但不完全正確。因為轉換的結果是純右值而不是左值。
C++17開始上述代碼保證執行mandatory copy elision。拋去cv限定后若初始化源物件純右值和目標物件型別相同,保證執行mandatory copy elision。這種情況下,保證不呼叫復制建構式,而不是之前的隱式呼叫(另外之前的復制構造不強制,所以之前復制構造的副作用不能被保證)。
而這種情況下,你的代碼和實際情況得到的結果應該截然相反,所以這邊不能用一個臨時左值來說明問題。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/17585.html
標籤:C++ 語言
上一篇:C語言呼叫Curl訪問https的程序中,在Client hello中的extension如何自定義或者修改
下一篇:菜鳥求問 關于 scanf_s
