1.实现不能被继承的类
思路:
将构造函数定义为私有的,因为子类创建对象是合成的,需要先调用父类的构造函数初始化父类成员,如果父类构造函数不可见,则不能被子类访问。
简记为:私有继承不可见,构造函数合成。
代码实现:
class A
{
public:
static A* GetObj1()//静态成员函数
{
return new A;//new对象
}
static A GetObj2()
{
return A();//使用匿名对象拷贝构造
}
private:
A()
{}
int _a;
};
class B : public A
{
private:
int _b;
};
int main()
{
A *p1 = A::GetObj1();
A a1 = A::GetObj2();
B b;
system("pause");
return 0;
}
2.实现一个类,定义的对象只在堆上
普通实现
思路1:同题1,new对象
代码实现:
class A
{
public:
static A* GetObj1()//静态成员函数
{
return new A;//new对象
}
static A GetObj2()
{
return A();//使用匿名对象拷贝构造
}
private:
A()
{}
int _a;
};
int main()
{
A *p1 = A::GetObj1();//在堆上
A a1(*p1);//栈上(1)
A a2 = *p1;//栈上(2)
system("pause");
return 0;
}
思路1的代码有缺陷:
上述(1),(2)两处对象在栈上,二者通过拷贝构造函数与赋值运算符重载实现。
优化实现
思路2:
防拷贝两个条件(同时存在):
(1)只声明不实现
(2)将拷贝构造、构造、赋值运算符重载都声明为私有的
代码实现:
class A
{
public:
static A* GetObj1()//静态成员函数
{
return new A;//new对象
}
static A GetObj2()
{
return A();//使用匿名对象拷贝构造
}
private:
A()
{}
A(const A& a);
A& operator=(const A&a);
int _a;
};
int main()
{
A *p1 = A::GetObj1();//在堆上
A a1(*p1);//栈上
A a2 = *p1;//栈上
system("pause");
return 0;
}
3.实现一个类,定义的对象只能存在栈上
思路:
同堆上
代码实现:
class A
{
public:
static A& GetObj2()
{
return A();//使用匿名对象拷贝构造
}
private:
A()
{}
int _a;
};
int main()
{
A a = A::GetObj2();
system("pause");
return 0;
}
4.实现一个类,定义出的对象不能在堆上
思路:
将动态分配空间的操作符声明为私有的
代码实现:
class AA
{
public:
private:
void* operator new(size_t size);
void operator delete(void* p);
int _aa;
};
int main()
{
AA aa=new AA;
}