函数
内联函数
如果一个函数事内联得,那么在编译时,编译器会把函数的代码副本放置在每个调用该函数的地方。
引入内联函数的目的事为了解决程序中函数调用效率的问题。内联函数内部不能有太复杂的逻辑,编译 器有时会有自己的优化策略,所以内联不一定起作用。 使用inline关键字创建
#include <iostream>
inline int MaxValue(int a, int b){
return a +b;
}
int main() {
int a=2,b=3;
int c = MaxValue(a,b);
std::cout<< c << std::endl;
return 0;
}
内联函数其实就是用空间换时间,函数调用对应很多操作,直接将被调用函数的内部逻辑拷贝到调用的地方。 所以逻辑不能太复杂,不然还是会失效。
类
c++ 使用struct,class来定义一个类 struct的默认成员权限事public,class的默认成员权限事private,除此之外,二者无差别
struct A {
string a;
string b;
union {
char aa;
int bb;
};
};
使用union来表示 aa 或 bb 只能有一个有值
class complex {
public:
complex(double r, double i);
virtual ~complex();
// 可以写在cpp文件内,但是简单的函数一般直接写这儿
// 编译器可能会做优化,优化成一个inline函数
double setReal(double d){
_real = d;
}
double getReal()const{
return _real;
}
double setImage(double i){
_image = i;
}
double getImage()const{
return _image;
}
private:
double _real;
double _image;
};
基础构造
class Complex {
private:
int _a;
int _b;
protected:
// 输出重载 const关键修饰 不允许改变
friend std::ostream& operator<<(std::ostream& os, const Complex &x);
// 输入重载
friend std::istream& operator>>(std::istream& is,Complex &x);
public:
void setA(const int a){_a = a;}
int getA(){return _a;}
void setB(const int b){_b = b;}
int getB(){return _b;}
// 默认构造函数
Complex();
// 构造函数
Complex(int a,int b);
// 拷贝构造
Complex(const Complex& x);
// 析构函数
virtual ~Complex();
// + 操作符重载
Complex operator+(const Complex& x);
// = 操作符重载
Complex operator=(const Complex& x);
// 前置 ++ 操作符
Complex& operator++();
// 后置 ++ 操作符
Complex operator++(int);
};
Complex::Complex() {
_a = 0;
_b = 0;
}
Complex::Complex(int a, int b) {
_a = a;
_b = b;
}
Complex::~Complex() {
cout << "~Complex" << endl;
}
Complex Complex::operator+(const Complex & x) {
// 会产生临时对象
// Complex tmp;
// tmp._a = x._a + _a;
// tmp._b = x._b + _b;
return Complex(_a + x._a,_b+x._b);
}
// 复制
Complex Complex::operator=(const Complex & x) {
if (this != &x){
_a = x._a;
_b = x._b;
}
return *this;
}
// 拷贝构造函数 防止产生副本
Complex::Complex(const Complex& x) {
_a = x._a;
_b = x._b;
}
// 前置 ++
Complex& Complex::operator++() {
_a++;
_b++;
return *this;
}
// 后置++
Complex Complex::operator++(int) {
Complex tmp(*this);
_a++;
_b++;
return tmp;
}
// 输出重载
std::ostream& operator<<(std::ostream& os, const Complex &x){
os << "a value is " << x._a << "b value is "<< x._b <<endl;
return os;
}
// 输入重载
std::istream& operator>>(std::istream& is,Complex &x){
// 使用空格或换行来赋值多个
is >> x._a >> x._b;
return is;
}
具体调用
int main() {
Complex a(1,2);
std::cout<< a.getA() << std::endl; // 1
std::cout<< a.getB() << std::endl; // 2
a.setA(2);
a.setB(1);
std::cout<< a.getA() << std::endl; // 2
std::cout<< a.getB() << std::endl; // 1
Complex b(2,3);
Complex c ;
c = a + b; // 若操作符 + 重载函数中使用了临时对象,就会有拷贝的过程
// Complex c = a + b; // 直接创建对象会少一个拷贝的步骤
// Complex d(c);// 使用存在对象创建一个新对象也会调用拷贝构造方法
// 输出重载
std::cout<< a << std::endl;
// 接受输入的值 并赋值
// int cc;
// std::cin >> cc;
// std::cout << cc <<std::endl;
// 输入重载
Complex e;
std::cin >> e;
std::cout << e << std::endl;
return 0; // text 代码区
}
头文件的重复包含问题
为了避免同一个文件被include多次,有两种方式
- 使用宏
#ifndef \__SOMEFILE_H\__
#define \__SOMEFILE_H\__
...
#endif
使用宏来防止同一个文件被多次包含,可移植性好,但是无法防止宏名重复,难以排错。
- #pragma once 使用编译器来防止同一个文件被多次包含;可防止宏名重复,易排错,但是可移植性不好
深拷贝/浅拷贝,写时复制
浅拷贝:只拷贝指针地址,c++默认拷贝构造函数于赋值运算符重载都是浅拷贝;节省空间,但 容易引发多次释放;
深拷贝:重新分配堆内存,拷贝指针指向内容。浪费空间,但不是导致多次释放。