蒂芙尼算什么档次| 吃饭后胃胀是什么原因| 手书是什么意思| 王羲之兰亭序是什么字体| 慕名而来是什么意思| 哼哈二将是什么意思| 小孩多动症是什么原因引起的| 欠是什么意思| 养肝护肝喝什么茶最好| 正痛片别名叫什么| 吃葡萄皮有什么好处| 圆脸适合什么发型| dhea是什么| 砂仁是什么东西| 中性粒细胞低吃什么药| 什么的贝壳| 笑什么如花| 耳鸣是什么原因引起| 白带什么时候来| 分率是什么意思| 银装素裹什么意思| 什么可以补气血| 胰岛素针头4mm和5mm有什么区别| zbc什么意思| 五月初七是什么星座| 什么鞋穿着舒服| 梦见别人家盖房子是什么意思| 黄芪喝多了有什么副作用| beside是什么意思| 胃口疼是什么原因| 什么是腹式呼吸| 梦见捉黄鳝是什么意思| 松子吃了有什么好处和坏处| 想长胖喝什么奶粉好| 狗狗为什么会咬人| 过敏性鼻炎引起眼睛痒用什么药| dfi是什么意思| 中国反导弹系统叫什么| 四肢麻木是什么病| 蝉鸣是什么季节| 本字五行属什么| 尿素氮高吃什么药| 手掌脱皮是什么原因| 低钾血症吃什么食补| 违和是什么意思| 荨麻疹有什么忌口吗| 手麻挂什么科| 小狗能吃什么| 宫颈阳性是什么意思| 恐龙灭绝的原因是什么| 三个降号是什么调| 圣母娘娘是什么神| 西汉与东汉有什么区别| 社区医院属于什么级别| 肺纹理增强是什么意思| 秋天穿什么衣服| 鱼露是什么| 空调睡眠是什么意思| 1938年属什么| 八一建军节什么生肖| 尿结晶高是什么原因| 拉稀吃什么药好| 牛肉不能跟什么一起吃| 大象什么颜色| 1997属什么| ab和ab生的孩子是什么血型| 睡衣什么面料最好| 用什么擦地最干净| 元五行属性是什么| 烫伤忌口不能吃什么| 女人喜欢什么样的阴茎| 阴道口瘙痒是什么原因| 肝主筋的筋是指什么| 周吴郑王是什么意思| 高中校长什么级别| 绿茶喝多了有什么危害| 左边脸长痘痘是什么原因| 老年人适合喝什么茶| 痛风是什么引起的| 佝偻病是什么样子图片| 梦见枪毙人是什么意思| 糖料病者应吃什么好| 阴道炎不能吃什么| 虾跟什么不能一起吃| 中午12点到1点是什么时辰| 肉桂茶属于什么茶| 毛主席的女儿为什么姓李| 五花大绑是什么意思| 班别是什么意思| 黄痰是什么原因造成的| 吊销是什么意思| 人工虎骨粉是什么做的| 新生儿超敏c反应蛋白高说明什么| 1999年出生属什么生肖| 六月十二号是什么星座| au990是什么金| 梅雨是什么| 潘海利根香水什么档次| 胃造影和胃镜有什么区别| 弹性是什么意思| 00年属什么生肖| 大姨妈黑色是什么原因| 婴儿长牙有什么症状| 什么主皮毛| 怀璧其罪是什么意思| 四曾念什么| 尿毒症是什么症状| 丝瓜吃了有什么好处| 金榜题名是什么生肖| 氯雷他定片主治什么| 低血压不能吃什么食物| 小孩过敏吃什么药最好| 桐字五行属什么| 什么是疣图片| 花甲是什么| 什么是尿毒症啊| 转氨酶高是什么原因引起的| 李倩梅结局是什么| 什么蔬菜补钾| 前庭功能减退是什么原因| 丰盈是什么意思| hpv长什么样| 细胞结构包括什么| 胃立康片适合什么病| gh是什么激素| 感知力是什么意思| vvip是什么意思| 农历五月二十一是什么星座| 梦见流鼻血是什么征兆| 是什么样的感觉我不懂是什么歌| 有妇之夫是什么意思| 耳朵疼什么原因| 牝是什么意思| 阴是什么意思| 脚麻看什么科室最好| 飞行员妻子有什么待遇| 印第安老斑鸠什么意思| 甲母痣挂什么科| 催供香是什么意思| 婴儿眉毛上黄痂是什么| 所言极是是什么意思| 思前想后是什么意思| 大脑供血不足吃什么药| 鸽子配什么煲汤最好| 庞统和诸葛亮什么关系| 檀郎是什么意思| 宦游人是什么意思| 双侧甲状腺弥漫病变是什么意思| 军区司令是什么级别| 萎缩性胃炎吃什么食物好| 心电轴重度左偏是什么意思| 乳腺腺体是什么| 眉头长痘痘是因为什么原因引起的| loveyourself什么意思| 天天喝可乐有什么危害| 为什么会缺铁| 12.21是什么星座| 混圈是什么意思| 正品行货是什么意思| 鼻涕臭是什么原因| 7月6号是什么星座| 便秘去药店买什么药吃| 威海有什么特产| 嘴唇上火起泡是什么原因| AX是什么意思| 唯小人与女子难养也什么意思| 回盲瓣呈唇形什么意思| 男性生殖器官叫什么| 部长是什么级别| 串门是什么意思| 嘴唇干是什么原因| 行李为什么叫行李| 鱼油有什么功效和作用| 毛豆吃多了有什么坏处| 6月30是什么星座| 香膏是什么| 结痂什么意思| ci是什么意思| 什么是特应性皮炎| 什么是编外人员| 手指甲紫色是什么原因| yy飞机票是什么| 猫是什么生肖| 兹有是什么意思| 汞中毒有什么症状| 维生素h的作用及功能主治是什么| 清明节一般开什么生肖| 吃月饼是什么生肖| 宫缩什么感觉| 孕酮代表什么| 胜字五行属什么| 橘子什么季节成熟| h是什么牌子的衣服| 女性肾虚吃什么补最好最快| 贝壳是什么垃圾| 脚掌麻木是什么原因| 黄芪什么味道| 吃虫草有什么好处| 胃痛吃什么药| 补充胶原蛋白吃什么最好| 婢女是什么意思| 跑步机cal是什么意思| 压到蛇了是有什么预兆| 骨密度检查是查什么| 痱子是什么样的图片| 猪冲蛇开什么生肖| 什么叫自私的人| 尿路感染吃什么消炎药| 6月22日什么星座| 结核抗体阴性代表什么| 梦见大火烧房子是什么意思| 怀孕了用排卵试纸测会显示什么| 减肥喝什么茶| 什么叫压缩性骨折| 梦里梦到蛇有什么预兆| 鱼上浮的原因是什么| 三陪是什么| 双龙是什么意思| 陆代表什么生肖| 骨髓不造血是什么病| 头皮痒用什么洗头好| 胃黏膜受损是什么症状| 梦见吃西红柿是什么意思| 多汗症看什么科| 微信英文名叫什么| 小猫吃什么| 月子能吃什么水果| 每天吃一个鸡蛋有什么好处| 淋巴细胞升高说明什么| 尿酸高是为什么| 尿亚硝酸盐阳性是什么意思| 血脂高吃什么蔬菜好| 中药不能和什么一起吃| abi是什么意思| 拧巴是什么意思| 尾款是什么意思| 孕妇吸二手烟对胎儿有什么影响| 灵芝泡酒有什么功效| 北属于五行的什么| 什么叫前列腺| 大骨节病是一种什么病| 翠字五行属什么| 小猫感冒吃什么药| 尿道发炎吃什么药| 逍遥丸配什么治失眠| 运动后体重增加是什么原因| 腰椎间盘突出和膨出有什么区别| 什么药可以当饭吃| 乌鸡白凤丸什么时候吃| 碟鱼是什么鱼| 美籍华人是什么意思| 什么药溶血栓最好| 为什么子宫会隐隐作痛| 得过且过什么意思| food什么意思| 水煎服是什么意思| 孕妇快生的时候有什么征兆| 农历3月3是什么节日| 肠粘连会有什么症状| 甲状腺低密度结节是什么意思| 健身有什么好处| gst是什么| 面包是什么做的| 手热是什么原因| 百度Jump to content

马艳丽透露为"澜湄会议"领导人制作礼服

From Wikipedia, the free encyclopedia
百度 “不知道我这种算不算‘海外定居’,需不需要注销户口?”张先生看到新规不无担心。

In the C++ programming language, a copy constructor is a special constructor for creating a new object as a copy of an existing object. Copy constructors are the standard way of copying objects in C++, as opposed to cloning, and have C++-specific nuances.

The first argument of such a constructor is a reference to an object of the same type as is being constructed (const or non-const), which might be followed by parameters of any type (all having default values).

Normally the compiler automatically creates a copy constructor for each class (known as an implicit copy constructor) but for special cases the programmer creates the copy constructor, known as a user-defined copy constructor. In such cases, the compiler does not create one. Hence, there is always one copy constructor that is either defined by the user or by the system.

A user-defined copy constructor is generally needed when an object owns pointers or non-shareable references, such as to a file, in which case a destructor and an assignment operator should also be written (see Rule of three).

Definition

[edit]

Copying of objects is achieved by the use of a copy constructor and an assignment operator. A copy constructor has as its first parameter a (possibly const or volatile) reference to its own class type. It can have more arguments, but the rest must have default values associated with them.[1] The following would be valid copy constructors for class X:

X(const X& copy_from_me);
X(X& copy_from_me);
X(volatile X& copy_from_me);
X(const volatile X& copy_from_me);
X(X& copy_from_me, int = 0);
X(const X& copy_from_me, double = 1.0, int = 42);
...

The first one should be used unless there is a good reason to use one of the others. One of the differences between the first and the second is that temporaries can be copied with the first. For example:

X a = X();     // valid given X(const X& copy_from_me) but not valid given X(X& copy_from_me)
               // because the second wants a non-const X&
               // to create a, the compiler first creates a temporary by invoking the default constructor
               // of X, then uses the copy constructor to initialize as a copy of that temporary. 
               // Temporary objects created during program execution are always of const type. So, const keyword is required.
               // For some compilers both versions actually work but this behaviour should not be relied 
               // upon because it's non-standard.

A similar difference applies when directly attempting to copy a const object:

const X a;
X b = a;       // valid given X(const X& copy_from_me) but not valid given X(X& copy_from_me)
               // because the second wants a non-const X&

The X& form of the copy constructor is used when it is necessary to modify the copied object. This is very rare but it can be seen used in the standard library's std::auto_ptr. A reference must be provided:

X a;
X b = a;       // valid if any of the copy constructors are defined
               // since a reference is being passed.

The following are invalid copy constructors because copy_from_me is not passed as reference (&) :

X(X copy_from_me);
X(const X copy_from_me);

because the call to those constructors would require a copy as well, which would result in an infinitely recursive call.

The following cases may result in a call to a copy constructor:

  1. When an object is returned by value
  2. When an object is passed (to a function) by value as an argument
  3. When an object is thrown
  4. When an object is caught by value
  5. When an object is placed in a brace-enclosed initializer list

These cases are collectively called copy-initialization and are equivalent to:[2] T x = a;

It is however, not guaranteed that a copy constructor will be called in these cases, because the C++ Standard allows the compiler to optimize the copy away in certain cases, one example being the return value optimization (sometimes referred to as RVO).

Operation

[edit]

An object can be assigned value using one of the two techniques:

  • Explicit assignment in an expression
  • Initialization

Explicit assignment in an expression

[edit]
Object a;
Object b;
a = b;       // translates as Object::operator=(const Object&), thus a.operator=(b) is called 
             // (invoke simple copy, not copy constructor!)

Initialization

[edit]

An object can be initialized by any one of the following ways.

a. Through declaration

Object b = a; // translates as Object::Object(const Object&) (invoke copy constructor)

b. Through function arguments

type function(Object a);

c. Through function return value

Object a = function();

The copy constructor is used only for initializations, and does not apply to assignments where the assignment operator is used instead.

The implicit copy constructor of a class calls base copy constructors and copies its members by means appropriate to their type. If it is a class type, the copy constructor is called. If it is a scalar type, the built-in assignment operator is used. Finally, if it is an array, each element is copied in the manner appropriate to its type.[3]

By using a user-defined copy constructor the programmer can define the behavior to be performed when an object is copied.

Examples

[edit]

These examples illustrate how copy constructors work and why they are sometimes required.

Implicit copy constructor

[edit]

Consider the following example:

import std;

struct Person {
    int age;

    explicit Person(int age): 
        age(age) {}
};

int main() {
    Person timmy(10);
    Person sally(15);

    Person timmy_clone = timmy;
    std::println("Timmy age: {}, Sally age: {}, Timmy clone age: {}", timmy.age, sally.age, timmy_clone.age);
    timmy.age = 23;
    std::println("Timmy age: {}, Sally age: {}, Timmy clone age: {}", timmy.age, sally.age, timmy_clone.age);
}

Output

10 15 10
23 15 10

As expected, timmy has been copied to the new object, timmy_clone. While timmy's age was changed, timmy_clone's age remained the same. This is because they are totally different objects.

The compiler has generated a copy constructor for us, and it could be written like this:

Person(const Person& other): 
    age{other.age} /* Calls the copy constructor of the age. */ {}

User-defined copy constructor

[edit]

Consider a very simple dynamic array class like the following:

import std;

class IntArray {
    std::size_t size;
    int* data;
public:
    explicit IntArray(int size): 
        size{size}, data{new int[size]} {}

    ~IntArray() {
        if (data) {
            delete[] data;
        }
    }

    [[nodiscard]]
    std::size_t getSize() const noexcept {
        return size;
    }

    int operator[](std::size_t index) const noexcept {
        return data[index];
    }
};

int main() {
    IntArray first(20);
    first[0] = 25;

    {
        IntArray copy = first;
        std::println("first[0] = {}, copy[0] = {}", first[0], copy[0]);
    }  // (1)

    first[0] = 10;  // (2)
}

Output

25 25
Segmentation fault

Since we did not specify a copy constructor, the compiler generated one for us. The generated constructor would look something like:

IntArray(const IntArray& other): 
    size{other.size}, data{other.data} {}

The problem with this constructor is that it performs a shallow copy of the data pointer. It only copies the address of the original data member; this means they both share a pointer to the same chunk of memory, which is not what we want. When the program reaches line (1), copy's destructor gets called (because objects on the stack are destroyed automatically when their scope ends). Array's destructor deletes the data array of the original, therefore, when it deleted copy's data, because they share the same pointer, it also deleted first's data. Line (2) now accesses invalid data and writes to it. This produces a segmentation fault.

If we write our own copy constructor that performs a deep copy then this problem goes away.

IntArray(const IntArray& other): 
    size{other.size}, data{new int[other.size]} {
    std::copy(other.data, other.data + other.size, data); 
}

Here, we are creating a new int array and copying the contents to it. Now, other's destructor deletes only its data, and not first's data. Line (2) will not produce a segmentation fault anymore.

Instead of doing a deep copy right away, there are some optimization strategies that can be used. These allow you to safely share the same data between several objects, thus saving space. The copy-on-write strategy makes a copy of the data only when it is written to. Reference counting keeps the count of how many objects are referencing the data, and will delete it only when this count reaches zero (e.g. boost::shared_ptr).

Bitwise copy constructor

[edit]

There is no such thing as "bitwise copy constructor" in C++. However, the default generated copy constructor copies by invoking copy constructors on members, and for a raw pointer member this will copy the raw pointer (i.e. not a deep copy).

Logical copy constructor

[edit]
It can be seen that in a logical copy constructor, a new dynamic member variable is created for the pointer along with copying the values.[4]

A logical copy constructor makes a true copy of the structure as well as its dynamic structures. Logical copy constructors come into the picture mainly when there are pointers or complex objects within the object being copied.

Explicit copy constructor

[edit]

An explicit copy constructor is one that is declared explicit by using the explicit keyword. For example:

explicit X(const X& copy_from_me);

It is used to prevent copying of objects at function calls or with the copy-initialization syntax.

See also

[edit]

References

[edit]
  1. ^ INCITS ISO IEC 14882-2003 12.8.2. [1] Archived 8 June 2007 at the Wayback Machine
  2. ^ ISO/IEC (2003). ISO/IEC 14882:2003(E): Programming Languages - C++ §8.5 Initializers [dcl.init] para. 12
  3. ^ INCITS ISO IEC 14882-2003 12.8.8. [2] Archived 8 June 2007 at the Wayback Machine
  4. ^ Computer Science A Structured Approach Using C++ by Behrouz A. Forouzan and Richard F. Gilberg, figure 10-9, page 507
孕早期吃什么 ccs医学是什么意思 嫩黄的什么 智商税什么意思 脂质是什么
高血糖喝什么茶好 屈光检查是什么 家里的财位在什么位置 炉甘石是什么 囊肿是什么
5月什么星座 cpr是什么 女人左眼下有痣代表什么 梦见怀孕是什么预兆 josiny是什么牌子
奥美拉唑与雷贝拉唑有什么区别 适当是什么意思 属狗的和什么属相最配 真菌阴性是什么意思 从胃到小腹连着疼是什么原因
hrd是什么职位hcv9jop6ns0r.cn 过敏性结膜炎用什么眼药水最好hcv8jop8ns7r.cn 人为什么会变hcv9jop3ns9r.cn 内火旺是什么原因gangsutong.com 鸡骨草有什么功效fenrenren.com
金鱼藻属于什么植物hcv9jop3ns5r.cn 感冒后咳嗽吃什么药520myf.com 什么是阻生牙wzqsfys.com 身份证号后四位代表什么hcv9jop4ns5r.cn 无花果什么时候成熟hcv7jop6ns0r.cn
肾结石可以吃什么水果weuuu.com 1974年属虎的是什么命hcv9jop0ns3r.cn 尿检粘液丝高什么意思hcv8jop1ns0r.cn 秋天有什么植物hcv9jop4ns9r.cn 白醋洗脸有什么效果hcv9jop8ns0r.cn
马加大是什么字hcv8jop3ns4r.cn 做梦吃鱼是什么意思hcv9jop6ns3r.cn 长颈鹿代表什么生肖hcv9jop7ns2r.cn 小孩吃什么能长高hcv7jop6ns3r.cn 紫色属于五行属什么hcv7jop7ns2r.cn
百度