c++语言的基础和构造函数

C++语言的简单输入输出

#include <iostream>
using namespace std;

int main()
{
	char str[20];
	cin >> str;			//键盘输入hello world
	cout << str << endl; //显示输出hello world
	system("pause");
	return 0;
}

输入函数:

1、cin

最基本,也是最常用的方法,接收一个字符,整形或字符串
遇到回车,TAB或空格结束

2、cin.get()

用法1:cin.get(字符变量名),可以用来接收单个字符
用法2:cin.get(字符数组名,接收字符的数目),可以用来接收一行字符串,可以包含空格

3、cin.getline()

原型:cin.getline(字符指针(char*),字符个数N(int),结束符(char));
cin.getline(字符指针(char*),字符个数N(int))
接收一行字符串,可以包含空格,与cin.get()用法2效果一样
主要适用于数组字符串,没有设置结束符默认以回车结束
cin.getline()属于istream流

4、getline()

原型:istream& getline ( istream &is , string &str , char delim(结束符) );
istream& getline ( istream &is , string &str );
用法:可以接收空格并输出,和cin.getline()类似,但cin.getline()属于istream流,getline()属于string流
getline(cin,s)获取一行字符串。

4、gets()

原型:char * gets ( char * str );
接受一个字符串,可以接收空格并输出

5、getchar()

原型:int getchar(void)
接受一个字符,这个函数在标准C里面就有,在C++里也有,是getc()的宏定义
拷贝构造函数
拷贝构造函数是一种特殊的构造函数,函数的名称必须和类名称一致,它必须的一个参数是本类型的一个引用变量。

一个拷贝构造函数简单例子

#include <iostream>  
using namespace std;  

class CExample {  
private:  
int a;  
public:  
//构造函数  
CExample(int b)  
{ a = b;}  
//一般函数  
void Show ()  
{  
 cout<<a<<endl;  
}  
};

int main()  
{  
CExample A(100);  
CExample B = A; //注意这里的对象初始化要调用拷贝构造函数,而非赋值  
 B.Show ();  
return 0;  
}

对象以值方式传入函数参数

#include <iostream>  
using namespace std;  

class CExample   
{  
private:  
 int a;  
  
public:  
 //构造函数  
 CExample(int b)  
 {   
  a = b;  
  cout<<"creat: "<<a<<endl;  
 }  
  
 //拷贝构造  
 CExample(const CExample& C)  
 {  
  a = C.a;  
  cout<<"copy"<<endl;  
 }  
   
 //析构函数  
 ~CExample()  
 {  
  cout<< "delete: "<<a<<endl;  
 }  
  
     void Show ()  
 {  
         cout<<a<<endl;  
     }  
};  
  
//全局函数,传入的是对象  
void g_Fun(CExample C)  
{  
 cout<<"test"<<endl;  
}  
  
int main()  
{  
 CExample test(1);  
 //传入对象  
 g_Fun(test);  
  
 return 0;  
}  
调用g_Fun()时,会产生以下几个重要步骤:
(1).test对象传入形参时,会先会产生一个临时变量,就叫 C 吧。
(2).然后调用拷贝构造函数把test的值给C。 整个这两个步骤有点像:CExample C(test);
(3).等g_Fun()执行完后, 析构掉 C 对象。

对象以值方式从函数返回

#include <iostream>  
using namespace std;  

class CExample   
{  
private:  
 int a;  
  
public:  
 //构造函数  
 CExample(int b)  
 {   
  a = b;  
 }  
  
 //拷贝构造  
 CExample(const CExample& C)  
 {  
  a = C.a;  
  cout<<"copy"<<endl;  
 }  
  
     void Show ()  
     {  
         cout<<a<<endl;  
     }  
};  
  
//全局函数  
CExample g_Fun()  
{  
 CExample temp(0);  
 return temp;  
}  
  
int main()  
{  
 g_Fun();  
 return 0;  
}  
当g_Fun()函数执行到return时,会产生以下几个重要步骤:
(1). 先会产生一个临时变量,就叫XXXX吧。
(2). 然后调用拷贝构造函数把temp的值给XXXX。整个这两个步骤有点像:CExample XXXX(temp);
(3). 在函数执行到最后先析构temp局部变量。
(4). 等g_Fun()执行完后再析构掉XXXX对象。

浅拷贝构造函数

所谓浅拷贝,指的是在对象复制时,只对对象中的数据成员进行简单的赋值,默认拷贝构造函数执行的也是浅拷贝。大多情况下“浅拷贝”已经能很好地工作了,但是一旦对象存在了动态成员,那么浅拷贝就会出问题了。

#include <iostream>  
using namespace std;  

class Rect  
{  
public:  
    Rect()      // 构造函数,p指向堆中分配的一空间  
    {  
        p = new int(100);  
    }  
    ~Rect()     // 析构函数,释放动态分配的空间  
    {  
        if(p != NULL)  
        {  
            delete p;  
        }  
    }  
private:  
    int width;  
    int height;  
    int *p;     // 一指针成员  
};  
  
int main()  
{  
    Rect rect1;  
    Rect rect2(rect1);   // 复制对象  
    return 0;  
}  

上面有一个bug,运行到后面,指向100的存储端有两个p,导致delete了两次100的内存空间,发生了错误。

深拷贝构造函数

在“深拷贝”的情况下,对于对象中动态成员,就不能仅仅简单地赋值了,而应该重新动态分配空间。

#include <iostream>  
using namespace std;  

class Rect  
{  
public:  
    Rect()      // 构造函数,p指向堆中分配的一空间  
    {  
        p = new int(100);  
    }  
    Rect(const Rect& r)  
    {  
        width = r.width;  
        height = r.height;  
        p = new int;    // 为新对象重新动态分配空间  
        *p = *(r.p);  
    }  
    ~Rect()     // 析构函数,释放动态分配的空间  
    {  
        if(p != NULL)  
        {  
            delete p;  
        }  
    }  
private:  
    int width;  
    int height;  
    int *p;     // 一指针成员  
};  
此时在rect1下的p和rect2下的p指向了不同的100存储空间。

防止默认拷贝操作

通过对对象复制的分析,我们发现对象的复制大多在进行“值传递”时发生,声明一个私有拷贝构造函数。甚至不必去定义这个拷贝构造函数,这样因为拷贝构造函数是私有的,如果用户试图按值传递或函数返回该类对象,将得到一个编译错误,从而可以避免按值传递或返回对象。

#include <iostream>  
using namespace std;  

class CExample   
{  
private:  
    int a;  
  
public:  
    //构造函数  
    CExample(int b)  
    {   
        a = b;  
        cout<<"creat: "<<a<<endl;  
    }  
  
private:  
    //拷贝构造,只是声明  
    CExample(const CExample& C);  
  
public:  
    ~CExample()  
    {  
        cout<< "delete: "<<a<<endl;  
    }  
  
    void Show ()  
    {  
        cout<<a<<endl;  
    }  
};  
  
//全局函数  
void g_Fun(CExample C)  
{  
    cout<<"test"<<endl;  
}  
  
int main()  
{  
    CExample test(1);  
    //g_Fun(test); 按值传递将出错  
      
    return 0;  
}   
发布了20 篇原创文章 · 获赞 1 · 访问量 2493

猜你喜欢

转载自blog.csdn.net/m0_46198325/article/details/105019220