C++点滴

本文介绍了C++中的引用作为函数返回值的格式、好处及注意事项,包括不能返回局部变量和new分配内存的引用。此外,讨论了C++的新特性如bool类型、随用随定义变量和I/O方式。还详细阐述了类的设计,包括访问限定符、对象实例化、成员访问以及构造函数、拷贝构造函数和析构函数的作用和使用。最后,提到了对象生命历程中的重要概念,如对象初始化、深拷贝和浅拷贝。
摘要由CSDN通过智能技术生成
  1. 将“引用”作为函数返回值类型的格式、好处和需要遵守的规则

函数格式:类型标识符(如int)&函数名(参数列表){函数体}
好处:返回的值不用创建副本。
注意事项:
1. 不能返回局部变量的引用。因为局部变量的引用在函数返回时会被销毁,使得引用指向不明,程序进入未知状态。
2. 不能返回函数内部new分配的内存的引用。被函数返回的引用只是一个临时变量,而没有被赋予一个实际变量,那么这个引用所指向的内存没法释放,会造成内存泄漏。
3. 可以返回类成员的引用,但是最好是const。因为类成员一般是封装隐藏的,不能被修改。

1.新特性
bool类型
bool flag=0;

if(flag)
{
    //to do
}
else
{
    //to do
}

2.随用随定义变量
3.C++的I/O方式
cout的语法形式
cout>>x>>endl;(endl相当于C语言中的/n)
cout<<”x+y=”<

namespace A         namespace B
{                   {
    int x=0;                int x=2;
    void fun1();            void fun1();
    void fun2();            void fun3();
}                   }

cout<

int *p=new int [1000];
if(NULL==p)
{
//内存分配失败
}
delete p;           //释放内存
p=NULL;     //将指针p置空

类(类名最好能看出类的功能)

class Dog               //类名(关键字)
{
char name[20];      //数据成员(属性)
int age;
int type;

void shout();           //成员函数(方法)
void run();
};

目的不同抽象出的信息不同。
访问限定符:public,private,protected
class TV
{
public:
char name[20]; //希望暴露出来的
int type;

void changeVol();
void power();
private:
电阻调节; //希望隐藏的
像素配色;
};
对象:具体事物
对象实例化
从栈实例化对象:(引用上面的类TV)
int main()
{
TV tv;
TV tv[20];
return 0;
}
从堆实例化对象:
int main()
{
TV *p=new TV();
TV *q=new TV[20];
//to do something
delete p;
delete []q;
return 0;
}
对象成员访问
单一:
tv.type=0; tv.changeVol(); (栈访问)
p->type=0; p->changeVol(); (堆访问)
数组:
int main()
{
TV *q=new TV[20];
for(i=0;i<20;i++)
{
q[i]->type=0;
q[i]->changeVol();
}
delete []q;
q=NULL;
return 0;
}
操作频繁且复杂的数据类型: char 数组(类型)
string类型

#include<iostream>
#include<string>
using namespace std;
int main()
{
string name=”Zhang san”;
string hobby(“football”);       //将football初始化给hobby:
cout<<name<<hobby<<endl;
return 0;
}
string s1;          //s1为空串
string s2(“abc”)    //s2被初始化为abc
string s3(s2)           //s3初始化为s2的一个副本
string s4(n,’c’)        //s4初始化为n个c

string s=”hello”+”world”;       //这种表达式错误,字符串之间不能直接相接
string s1=”a”+s2;               //合法

封装的好处

class Student
{
public:
void set_age(_age)              //这也称为类内定义
{
if(_age>0&&_age<100)        //通过封装限制了age的设置条件
{
age=_age;
}
else
.....
}
void get_age()
{
return age;
}
private:
string name;
int age;
...
};
class Car
{
public:
get_Wheelcount()            //封装使得这个函数是只读形式
{return Wheelcount;}
private:
int Wheelcount;
};

类内定义与内联函数 类内定义的函数编译器自动定义为内联函数
类外定义
同文件类外定义:

class Car
{
public:
void run();
void stop();
void changespeed();
};

void Car::run(){…};
void Car::stop(){…};
void Car::changespeed(){…};
分文件类外定义:
编写一个头文件Car.h

class Car
{
public:
void run();
void stop();
void changespeed();
};

编写一个源文件Car.cpp

#include”Car.cpp”
void Car::run(){...};
void Car::stop(){...};
void Car::changespeed(){...};

内存分区
栈区 int x=0;int *p=NULL;
堆区 int *p=new int[20];
全局区 存储全局变量和静态变量
常量区 string str=”hello”;
代码区 存储逻辑代码的二进制
对象初始化
构造函数
特点
在对象实例化时被自动调用;构造函数与类同名;构造函数没有返回值;构造函数可以有多个重载形式;实例化对象时仅用到一个构造函数;当用户没有定义构造函数时,编译器自动生成一个构造函数。
无参构造函数

class Student
{
public:
Student()
{m_strName=”jim”;}
private:
string m_strName;
};

有参构造函数

class Student
{
public:
Student(string _name)
{m_strName=_name;}
private:
string m_strName;
};

重载构造函数

class Student
{
public:
Student()
{m_strName=”jim”;}
Student(string _name)
{m_strName=_name;}
private:
string m_strName;
};

初始化列表

class Student
{
public:
Student():m_strName(“Jim”),m_iAge(15){}
private:
m_strName;
m_iAge;
};

初始化列表的特性:初始化列表先于构造函数执行;初始化函数只能用于构造函数;初始化列表可以同时初始化多个数据成员
初始化列表的重要性

class Circle
{
public:
Circle(){m_dpi=3.14}                //错误  因为已经将m_dpi限定了,不能再赋值了
private:
const double m_dpi;
};
class Circle
{
public:
Circle():m_dpi(3.14){}              //正确
private:
const double m_dpi;
};

拷贝构造函数
定义格式:
类名(const 类名&变量名)

class Student
{
public:
Student();
{
m_strName=”Tom”;
}
Student(const Student&stu){...};
private:
string m_strName;
};

如果没有自定义拷贝构造函数,则系统会自动生成一个默认的拷贝构造函数
当采用直接初始化或者复制初始化实例化对象时,系统自动调用拷贝构造函数
拷贝构造函数不能重载
析构函数(释放资源)
定义格式:~类名()

class Student
{
public:
Student() {m_pName=new char[20];}
~Student() {delete []m_pName;}
private:
char *m_pName;
};

如果没有自定义的析构函数,则系统自动生成;
析构函数在对象销毁时自动调用;
析构函数没有返回值和参数,也不能重载
对象的生命历程
1.申请内存->2.初始化列表->3.构造函数->4.参与运算->5.析构函数->6.释放内存
对象数组

class Coordinate
{
public:
int m_iX;
int m_iY;
};
int main()
{
Coordinate coord[3];
coord[1].m_iX=3;
Coordinate *p=new Coordinate[3];
p[0].m_iX=10; p[0]->m_iX=17;
delete []p;
p=NULL;
return 0;
}

对象成员

class Coordinate
{
public:
Coordinate(int x,int y);
private:
int m_iX;
int m_iY;
};
class Line
{
public:
Line(int x1,int y1,int x2,int y2);
private:
Coordinate m_coorA;         //数据类型是Coordinate 
Coordinate m_coorB;
};

Line::Line(int x1,int y1,int x2,int y2):m_coorA(x1,y1),m_coorB(x2,y2)
{
cout<<”Line”<<endl;                         //Line的构造函数
}
int main()
{
Line *p=new Line(2345);
delete p;
p=NULL;
return 0;
}

浅拷贝

class Array
{
public:
Array()
{m_iCount=5;}
Array(const Array& arr)
{m_iCount=arr.iCount;}
private:
    int m_iCount;   
};

深拷贝

class Array
{
public:
Array()
{m_iCount=5,m_pArr=new int[m_iCount];}      
Array(const Array& arr)
{m_iCount=arr.m_iCount;
m_pArr=new int[m_iCount];
for(i=0;i<m_iCount;i++)
{m_pArr[i]=arr.m_pArr[i];}}
private:
    int m_iCount;
int *m_pArr;
};

对象指针

class Coordinate
{
Coordinate *p=new Coordinate;
p->m_iX=10;  //(*p).m_iX=10;
p->m_iY=15;  //(*p).m_iY=15;
delete p;
p=NULL;
return 0;
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值