一、拷贝构造
当你使用一个实例对象去初始化另一个实例对象的时候,这两个实例对象使用的是同一个内存空间。
#include <iostream>
using namespace std;
class Player
{
private:
int *i;
public:
Player()
{
this->i = (int *)malloc(sizeof(int));
*this->i = 10;
cout << "constrcut" << endl;
}
~Player()
{
if (!this->i)
return;
cout << "in destrcut address = " << this->i << endl;
free(this->i);
}
void run()
{
cout << "run i = " << this->i << endl;
}
};
int main(void)
{
Player p1;
Player p2 = p1;
p1.run();
p2.run();
}
如以上代码,构造函数会被调用一次,而析构函数会被对此调用。 p2是一个新的变量,是被p1对象进行直接赋值的。 这就意味着他们是共用同一内存空间。
那么问题来了,在不改变main方法中的代码的情况下,如何分配不同的内存空间给这两个对象?
答案就是拷贝构造。
拷贝构造函数用于拷贝对象。也就是说,这个构造函数的参数是这个类的对象,执行这个构造函数之后,会产生一个与原来对象一样的对象(实际上是用原来对象的数据初始化了一个对象)。
二、静态成员
- 如果类中有静态成员,则编译器会当作这是一个声明而已,表明在这个文件的某处,你必须定义它。
#include <iostream>
class A
{
private:
static int i;
public:
A(){};
void print() { std::cout << i << std::endl; };
void set(int ii) { i = ii; };
};
int A::i = 12; // 必须要定义,否则会报linker错误
int main(void)
{
A a;
a.print();
}
- 初始化列表只能对非静态变量进行初始化。
- 静态成员方法可以直接通过这个类名加上方法名去访问。
- 静态成员函数只能访问静态的成员变量(因为没有this)。
#include <iostream>
class A
{
private:
static int i;
public:
A(){};
void print() { std::cout << i << std::endl; };
void set(int ii) { i = ii; };
static void say(int ii) { std::cout << ii << this->i << std::endl; }; // this只能用于非静态成员函数内部。
};
int A::i = 12;
int main(void)
{
A a;
a.print();
A::say(0);
}
三、模板
#include <iostream>
template <typename T>
void print(T value)
{
std::cout << value << std::endl;
};
int main(void)
{
print(1);
print(2.3);
print("hello");
}
C++中的模板就相当于TS中的泛型