C/C++(C++返回对象与应用区别,类成员的存储)

返回对象与应用区别:

拷贝构造器发生的时机:

1.构造新对象 A a, A b = a;
2.传参或返回对象

对于普通变量来说,传引用效果不是很明显,对于类对象而言,传对象效果很高。
传引用等价于扩大了原对象的作用域。

#include<iostream>
using namespace std;
class A
{
public:
    A()//无参构造器
    {
        cout<<this<<" constructor"<<endl;
    }
    ~A()//析构器
    {
        cout<<this<<" destructor"<<endl;
    }
    A(const A & another)//拷贝构造器
    {
        cout<<this<<" cpy constructor from"<<&another<<endl;
    }
    A & operator=(const A & another)//运算符重载
    {
        cout<<this<<" operator"<<&another<<endl;
    }
};

void func(A a)
{
    
}
void func1(A &a)
{

}

int main()
{
    A x;//调用构造器
    A y = x;//拷贝构造器
    func(x);//调用拷贝构造器
/*
0x61fe9e constructor
0x61fe9d cpy constructor from0x61fe9e
0x61fe9f cpy constructor from0x61fe9e
0x61fe9f destructor
0x61fe9d destructor
0x61fe9e destructor
有构造器就有析构器
*/  
    
    func1(x);//没有调用任何构造器
/*
0x61fe9e constructor
0x61fe9d cpy constructor from0x61fe9e
0x61fe9f cpy constructor from0x61fe9e
0x61fe9f destructor
0x61fe9d destructor
0x61fe9e destructor
*/
    
    return 0;
}


栈上的对象是可以返回的,但不能返回栈上的引用(除非返回对象本身)。

#include<iostream>
using namespace std;
class A
{
public:
    A()//无参构造器
    {
        cout<<this<<" constructor"<<endl;
    }
    ~A()//析构器
    {
        cout<<this<<" destructor"<<endl;
    }
    A(const A & another)//拷贝构造器
    {
        cout<<this<<" cpy constructor from"<<&another<<endl;
    }
    A & operator=(const A & another)
    {
        cout<<this<<" operator"<<&another<<endl;
    }
};

A func(A &a)
{
    return a;
}

int main()
{
    A x;//调用构造器
    func(x);//发生了一次拷贝构造,但上述没有返回值的时候是没有任何构造器 
/*
0x61feae constructor
0x61feaf cpy constructor from0x61feae
0x61feaf destructor
0x61feae destructor
*/
    return 0;
}

int main()
{
    A x;//调用构造器
    A t;//调用构造器
    t = func1(x);//x作为参数传入并没有调用构造器,而是返回大时候调用了拷贝构造器,(func1函数返回的值拷贝到临时变量中,再从临时变量拷贝到t,用来运算符重载)
    cout<<"&t "<<&t<<endl;
/*
0x61fe9e constructor
0x61fe9d constructor
0x61fe9f cpy constructor from0x61fe9e
0x61fe9d operator0x61fe9f
0x61fe9f destructor
&t 0x61fe9d
0x61fe9d destructor
0x61fe9e destructor
*/
    return 0;
}
A func()
{
    A b;
    return b;
}
int main()
{
    A t;
    t = func();
    cout<<"&t "<<&t<<endl;

/*
0x61fe9e constructor
0x61fe9f constructor
0x61fe9e operator0x61fe9f
0x61fe9f destructor
&t 0x61fe9e
0x61fe9e destructor
*/

    return 0;
}
A& func()
{
    A b;
    return this;//是可以的,因为本身对象还没有销毁,如果返回的是b,返回后func销毁,有时候会正确,有时候会错误。
}

string类字符拼接的实现

mystring mystring::operator+(const mystring & another)
{
    mystring tmp;//
    delete []tem._str;
    int len = strlen(this->_str);
    len += strlen(another._str);
    tmp._str = new char[len+1];

    memset(tem._str,0,len+1);//必须要的
    strcat(tem._str,this->_str);
    strcat(tem._str,another._str);
    return tmp;
}

c与c++关于字符串的处理对比
c基于字符数组,利用一些方法strcpy,strlen,strcat等操作。
c++所有操作围绕字符指针。通过此指针进行操作,整体设计思想是面向对象思想。

面向对象的思想练习

#include<iostream>
#include<unistd.h>
#include<iomanip>
#include<time.h>

using namespace std;
class Clock
{
private:
    int hour;
    int min;
    int sec;
public:
    Clock()
    {
        time_t t = time(NULL);
        struct tm ti = *localtime(&t);
        hour = ti.tm_hour;
        min = ti.tm_min;
        sec = ti.tm_sec;
    }
    void run()
    {
        while(1)
        {
            show();//显示函数
            tick();//数据跟新函数
        }
    }
private:
    void show()
    {
        system("cls");//windows下的清屏cls
        cout<<setw(2)<<setfill('0')<<hour<<":";
        cout<<setw(2)<<setfill('0')<<min<<":";
        cout<<setw(2)<<setfill('0')<<sec;
    }
    void tick()
    {
        sleep(1);
        if(++sec == 60)
        {
            sec = 0;
            min += 1;
            if(++min == 60)
            {
                min = 0;
                hour += 1;
                if(++hour == 24)
                {
                    hour = 0;
                }
            }
        }
    }
}

int main()
{
    Clock c;
    c.run();

    return 0;
}

类成员的存储

#include<iostream>
using namespace std;
class Time
{
private:
    int hour;
    int min;
    int sec;
public:
    Time(int h,int m,int s)
        :hour(h),min(m),sec(s)
        {
        
        }
    void display()
    {
        cout<<hour<<min<<sec<<endl;
        //<=>
        //cout<<this->hour<<this->min<<this->sec<<endl;
    }
/*
    void display(Time *t)
    {
        cout<<t->hour<<t->min<<t->sec<<endl;//自己通过显式传参。
    }
*/

};
int main()
{
    Time t(1,2,3),t1(2,3,4),t2(4,5,6);
    cout<<sizeof(Time)<<"----"<<sizeof(t)<<endl;
    t.display();
    t1.display();
    t2.display();

    return 0;
}

上述代码display()函数,三个对象公用。对象在调用的时候传递了自己对象this。
对象拥有自己的存储空间,函数部分代码是公用的。表现的形式是每个对象在调用的时候传进自己的对象this。

注意事项

1,不论成员函数在类内定义还是在类外定义,成员函数的代码段都用同一种方式存储。
2,不要将成员函数的这种存储方式和 inline(内置)函数的概念混淆。inline 的逻辑意义是将函数内嵌到调用代码处,减少压栈与出栈的开支。
3,应当说明,常说的“某某对象的成员函数”,是从逻辑的角度而言的,而成员函数的存储方式,是从物理的角度而言的,二者是不矛盾的。类似于二维数组是逻辑概念,而物理存储是线性概念一样。

原文地址:https://www.cnblogs.com/intelwisd/p/8547021.html