构造函数
构造函数长什么样子 - 函数名与类名相同 - 没有返回值 void也是有返回值值的
- 如果不写构造函数,任何类中都存在一个默认的构造函数 默认的构造函数是无参的
当我们写了构造函数,默认的函数就被删掉了
- 构造函数在构造对象的时候,默认调用 - delete可以用来删掉默认的构造函数 类名()=delete;
-指定使用默认的无参构造函数,用default说明 类名() = default;
- 允许构造函数调用另一个构造函数,只是要用初始化参数列表的方式 - 初始化参数列表:只有构造函数有 构造函数名(参数1,参数2...):成员1(参数1),成员2(参数2)...{} (避免形参命和数据成员命相同导致的问题)
构造函数是用来干嘛的 -用来构造对象的 - 构造函数更多是用来树池话数据成员的 构造函数的几个思考题 -为什么不写构造函数可以构造对象?(因为存在一个默认的无参构造函数,所以再不写的时候,只可以构造无参的对象) - 构造函数为什么要重载?(为了构造不同长相的对象)
class Tihu1 {
public :
Tihu1 ( string nname = "Tihu" , int nage = 19 ) : name ( nname) , age ( nage) { }
void print ( ) {
cout<< name<< "\t" << age<< endl;
}
protected :
string name ;
int age ;
} ;
class Tihu2 {
public :
Tihu2 ( string nname = "Tihu二" , int nage = 19 ) {
name = nname;
age = nage;
}
void print ( ) {
cout<< name<< "\t" << age<< endl;
}
protected :
string name ;
int age ;
} ;
int main ( void ) {
Tihu1 A1 ( "Tihu1" , 20 ) ;
Tihu1 A2 ( "Tihu2" , 21 ) ;
Tihu2 A3;
A1. print ( ) ;
A2. print ( ) ;
A3. print ( ) ;
return 0 ;
}
析构函数
析构函数长什么样子
无返回值 无参数 函数名:类名 不写的话存在默认的析构函数 析构函数不需要自己调用,在对象的生命周期结束的时候执行 析构函数是用来干嘛的 -当类中数据成员是指针的时候,用动态内存申请写构造函数以及析构函数 - 释放数据成员申请的动态内存
class Tihu2 {
public :
Tihu2 ( const char * nname = "Tihu" , int nage = 19 ) {
name = new char [ strlen ( nname) + 1 ] ;
strcpy ( name, nname) ;
cout<< strlen ( nname) + 1 << endl;
age = nage;
}
void print ( ) {
cout<< name<< "\t" << age<< endl;
}
~ Tihu2 ( ) {
cout<< "我是析构函数" << endl;
delete [ ] name;
}
protected :
char * name ;
int age ;
} ;
拷贝构造函数
拷贝构造函数也是一个构造函数,长相与构造函数相同,也是用来构造对象的,只是 参数是唯一的,是对对象的引用 Tihu(const Tihu& A1 )
不写的话也是存在默认的拷贝构造该函数,不过这个默认的是浅拷贝,在元素含有指针的时候不适用。 拷贝构造函数的作用:用一个对象去初始化另一个对象 当存在匿名对象赋值操作的时候,必须加const
class Tihu
{
public :
Tihu ( const Tihu& A1)
{
age = A1. age;
}
protected :
int age;
}
深拷贝与浅拷贝
浅拷贝:默认的拷贝构造为浅拷贝 深拷贝:拷贝构造中做了new的内存操作,因为浅拷贝再有指针的情况下,只是给指针确定的指向,并不是给指针申请新的空间,导致在析构函数里,内存释放会出错
class Tihu
{
public :
Tihu ( char nname[ ] = "Tihu" , int nage = 19 ) : age ( nage)
{
name = new char [ strlen ( nname) + 1 ] ;
strcpy ( name, nname) ;
}
Tihu ( const Tihu& A1)
{
name = new char [ sizeof ( * A1. name) ] ;
strcpy ( name, A1. name) ;
}
~ Tihu ( )
{
delete [ ] name;
}
protected :
char * name;
int age;
}
Tihu A1 ( "Tihu1" , 10 ) ;
Tihu A2 ( A1) ;
printf ( "A1.name:%p\n" , A1. name) ;
printf ( "A2.name:%p\n" , A2. name) ;
构造与析构顺序
普通对象,构造顺序和析构顺序是相反的 new出来的对象,delete会直接调用析构函数 static对象,当程序关闭的时候,生命周期才会结束
# include <iostream>
# include <string>
using namespace std;
class MM
{
public :
MM ( string name= "x" ) : name ( name) {
cout << name;
}
~ MM ( ) {
cout << name;
}
protected :
string name;
} ;
int main ( )
{
{
MM mm1 ( "A" ) ;
static MM mm2 ( "B" ) ;
MM* p3 = new MM ( "C" ) ;
MM mm4[ 4 ] ;
delete p3;
p3 = nullptr ;
}
return 0 ;
}
C++结构体
在c++的结构体中,如果加了构造函数,那么必须使用c++类的方式是使用这个结构体,唯一的区别就是结构体中的默认区域为公共属性,而类中的默认区域为私有属性。
作业
mystring类的实现
实现string中创建方式 通过实现data和c_str函数 打印字符串 实现append 实现字符串的链接 实现字符串比较 手写析构函数释放内存
# include <iostream>
# include <cstring>
using namespace std;
class mystring
{
public :
mystring ( char str1[ ] = "默认值" ) {
str = new char [ strlen ( str1) + 1 ] ;
strcpy ( str, str1) ;
}
mystring ( const mystring& object) {
str = new char [ strlen ( object. str) + 1 ] ;
strcpy ( str, object. str) ;
}
~ mystring ( ) {
delete [ ] str;
}
char * data ( ) {
return str;
}
char * c_str ( ) {
return str;
}
void print ( ) {
cout<< str<< endl;
}
mystring append ( const mystring& object) {
int n= strlen ( str) ;
int sum = n+ strlen ( object. str) + 1 ;
char * ptemp = new char [ sum] ;
int i= 0 ;
while ( 1 ) {
if ( i< strlen ( str) ) {
ptemp[ i] = str[ i] ;
}
else if ( i>= strlen ( str) && i< sum- 1 ) {
ptemp[ i] = object. str[ i- n] ;
}
else {
ptemp[ i] = 0 ;
break ;
}
}
mystring A1 ( ptemp) ;
delete [ ] ptemp;
ptemp = NULL ;
return A1;
}
int compare ( const mystring& object) {
return strcmp ( str, object. str) ;
}
protected :
char * str;
} ;
int main ( ) {
mystring str1;
mystring str2 ( "ILoveyou" ) ;
mystring str3 ( str1) ;
str3. print ( ) ;
mystring str4 = str2;
str4. print ( ) ;
cout << str2. c_str ( ) << endl;
cout << str2. data ( ) << endl;
string strOne= "one" ;
string strTwo= "two" ;
string strThree= strOne. append ( strTwo) ;
cout<< strThree. data ( ) << endl;
cout<< strOne. compare ( strOne) << endl;
cout<< strOne. compare ( strTwo) << endl;
cout<< strTwo. compare ( strOne) << endl;
return 0 ;
}
运行结果