c++拷贝构造和编译优化

#include <iostream>

using namespace std;

class MyClass
{
public:
   MyClass();
   MyClass(int i);
   MyClass(const MyClass &c);
   ~MyClass();

   //后面main中测试发现func1 和func2之后没有调用拷贝构造,应该是被优化了
   MyClass  func1(int i){
                cout<<"func1"<<endl;
                return MyClass(0);
   }
   MyClass  func2(int i){
            MyClass a;
                cout<<"func2"<<endl;
                return a;
   }  

private:
   int m_i;

};

MyClass::MyClass()
{
    m_i = 0;
    cout << "MyClass()" << endl;
}
MyClass::MyClass(int i)
{
    m_i = i;
    cout << "MyClass(int i)" << endl;
}

MyClass::MyClass(const MyClass &c)
{
    m_i = c.m_i;
    cout << "MyClass(const MyClass &c)" << endl;
}

//这里调用了两次拷贝构造函数&c
MyClass test(const MyClass c)
{
    cout << "test" << endl;
        return c;
}

MyClass::~MyClass()
{
        cout<<"~"<<endl;
}

int main()
{
        MyClass c2;
    cout << "-------------------------------" << endl;
    MyClass c1=c2.func2(2);
    cout << "-------------------------------" << endl;
        MyClass c3=test(c2);
    cout << "-------------------------------" << endl;

    return 0;
}

//结果如下
MyClass()
-------------------------------
func1
MyClass(int i)
-------------------------------
MyClass()
func2
-------------------------------
MyClass(const MyClass &c)
test
MyClass(const MyClass &c)
~
-------------------------------

  扩展

将拷贝构造函数声明为explicit,则会阻止隐式拷贝构造函数的调用.隐式拷贝构造函数的调用主要发生在三个点:

1.一个对象作为函数参数,以值传递的方式传入函数体

2.一个对象作为函数返回值,以值传递的方式从函数返回

3.以AAA = xxx的方式创建对象AAA,xxx为与AAA为同类型的对象.

因而,将拷贝构造函数声明成explicit并不是良好的设计,一般只将有单个参数的constructor声明为explicit,而copy constructor不要声明为explicit.

参考http://www.cnblogs.com/dwdxdy/archive/2012/07/17/2595479.html

时间: 2024-10-18 21:26:36

c++拷贝构造和编译优化的相关文章

引用 拷贝构造 赋值语句

1.引用 C++中有一种新的数据类型,对已开辟空间在取一个名字: 就是别名,不开辟新的空间,没有空引用: 例:int &b; 错误, 交换两个数字用引用实现: 常见的几种引用形式: (1).对变量引用:int a = 10; int &b = a; (2).对指针引用:int *p = &a; int *&q = p; (3).对数组引用:int ar[3] = {1, 2, 3,}; int (&b)[3] = ar; 此外还有以下类型的引用: (1).常引用 c

C++基本函数的调用优化(构造、拷贝构造、赋值)

合理的函数可提升时间和空间的利用率 //Test1.h #include<iostream> using namespace std; struct ST { private: int a; short b; public: ST(int a=0, short b=0):a(a),b(b) { this->a = a; this->b = b; cout<<"Object was Built. "<<this<<endl; }

拷贝构造,深度拷贝,关于delete和default相关的操作,explicit,类赋初值,构造函数和析构函数,成员函数和内联函数,关于内存存储,默认参数,静态函数和普通函数,const函数,友元

 1.拷贝构造 //拷贝构造的规则,有两种方式实现初始化. //1.一个是通过在后面:a(x),b(y)的方式实现初始化. //2.第二种初始化的方式是直接在构造方法里面实现初始化. 案例如下: #include<iostream> //如果声明已经定义,边不会生成 class classA { private: int a; int b; public: //拷贝构造的规则,有两种方式实现初始化 //1.一个是通过在后面:a(x),b(y)的方式实现初始化 //2.第二种初始化的方式是直

【C/C++学院】0819-/类的成员函数与const-mutable /构造与析构/拷贝构造deletedefault以及深浅拷贝/静态成员函数成员变量类在内存的存储默认参数/友元类以及友元函数

类的成员函数与const-mutable 成员函数 Fushu.h #pragma once #include <iostream> class fushu { public: int x; int y; public: fushu(); ~fushu(); void show(); inline void showall(int x, int y);//显式内联 void setxy(int x, int y);//编译器优化,默认隐式内联 void show(int x, int y);

C++之拷贝构造与拷贝赋值

拷贝构造和拷贝赋值------一个有点难的问题 介绍之前,我们需要首先了解深拷贝与浅拷贝的差异: 何为深拷贝,深拷贝不会复制指针,而是令目标对象拥有独立的资源,该资源是从元对象中复制,即先找到对象的指针,在通过指针拷贝其内容: 何为浅拷贝,即之赋值指针的地址,不会赋值指针的目标,容易引发double free异常,即多个目标指向同一个内存: 缺省拷贝构造函数和缺省拷贝赋值函数 如果一个类没有显示的定义一个拷贝构造函数和拷贝赋值运算符,则编译器会为其默认提供一个,但是这个函数只能进行浅拷贝: 如果

AVRStudio 的编译优化级别

-00 无优化. -01 减少代码尺寸和执行时间,不进行需要大量编译时间的优化. -02 几乎执行所有优化,而不考虑代码尺寸和执行时间. -03 执行 -02 所有的优化,以及内联函数,重命名寄存器的优化. -0S 针对尺寸的优化.执行所有 -02 优化而不增加代码尺寸. 设置方法: 1.不使用外部的makefile 2.使用外部的makefile AVRStudio 的编译优化级别,布布扣,bubuko.com

数据结构之二叉树 (构造 拷贝构造 以及前序中序后续三种遍历方法)

首先二叉树的节点定义如下: struct BinaryNode {                  BinaryNode *_left;                  BinaryNode *_right;                  T _data;                 BinaryNode( T data ) :_data(data), _left( NULL), _right(NULL )                 {}; }; 二叉树的结构以及接口如下 te

C++ 拷贝构造

在C++存在拷贝构造函数,拷贝构造函数与不同构造函数形成重载(这一点很重要),这就意味着(要么class入口为普通构造函数,要么为拷贝构造函数,不可能2个都会执行的).好了 , 下面可是今天的Studying 一 , 实际上C++类中有一个默认的拷贝构造,它的作用是将此类中非static成员逐一copy.现在先不管默认的Copy构造,我先先重载一下Copy构造: #include <iostream> using namespace std; class copyC { public:    

关于java字符串编译优化问题

情景一:不好的字符串拼接习惯    起因是这样的:一个大牛在写了一篇关于java字符串优化问题的讲解,他提到:不要使用strObj+otherValue的方法将otherValue转换为字符串形式,因为底层操作会让你吓一跳的.那么底层的实质是怎么样的呢?他的意思是这样的: 比如:    String s = "I have"; int  total = 12; Dog dog = new Dog();     //假设Dog类重写了toString方法 String msg = s +