C/C++编程:noncopyable原理及实现

实现

在C++中,类的拷贝:

  • 通过拷贝构造函数和赋值构造函数。
  • 就是专门为拷贝实现的成员方法。

由于拷贝构造函数和赋值构造函数在用户没有提供的情况下是c++编译器自动生成的,而且是public成员,因此默认的c++类都有拷贝赋值功能

class A {
    int val;
};
int main() {
    A a;
    A b = a;
    return 0;
}

如果想要一个C++类不能被拷贝,可以显示的声明类的拷贝构造函数和赋值函数为私有函数,从而达到该类不可被拷贝的目的

  1. C++11前的noncopyable
#ifndef NOCOPYABLE_H
#define NOCOPYABLE_H
/*
class noncopyable的基本思想是把构造函数和析构函数设置protected权限,这样子类可以调用,但是外面的类不能调用,那么当子类需要定义构造函数的时候不至于通不过编译。但是最关键的是noncopyable把拷贝构造函数和拷贝赋值函数做成了private的,继承自noncopyable的类在执行拷贝操作时会调用基类的拷贝操作,但是基类的拷贝操作是private的,因此无法调用,引发编译错误。
*/
class nocopyable {
protected:
  nocopyable(){};
  ~nocopyable(){};
private:  //
  nocopyable(const nocopyable& );
  nocopyable& operator=(const nocopyable& );
};

#endif //NOCOPYABLE_H

  1. C++11之后noncopyable
/*
基本思想是: 把构造函数和析构函数设置为protected权限,这样子类可以调用,但是外面的类不能调用。

最关键的是将noncopyable把拷贝构造函数和拷贝赋值函数做成
*/
class noncopyable
{
 public:  //delete表示禁止类的拷贝赋值操作
  noncopyable(const noncopyable&) = delete;
  void operator=(const noncopyable&) = delete;

 protected:  // 可以构造和析构函数
  noncopyable() = default;
  ~noncopyable() = default;
};

怎么使用:只需要继承该类就可以保证派生类不可复制

class A : public nocopyable {};

int main() {
    A a1;
    A a2 = a1; // 错误:使用了被删除的函数‘A::A(const A&)’
    return 0;
}

说明:

  1. =delete
  • 在C++11中,如果想要禁止类的拷贝行为只需要把相应的函数设为 = delete即可 .
  • =delete函数,编译器会对指定的函数禁用,从而避免了某些非法的函数调用或者类型转换,从而提高了代码的安全性。
  1. C++11 标准引入了一个新特性:"=default"函数。程序员只需在函数声明后加上“=default;”,就可将该函数声明为 "=default"函数,编译器将为其自动生成默认的函数定义体,提高代码的执行效率。

测试


class A : private noncopyable
{
public:
    A() {}
    virtual ~A() {}
protected:
private:
};

class B : public A
{
public:
    B() {}
    virtual ~B() {}
protected:
private:
};

class C : public B
{
public:
    C() {}
    ~C() {}
protected:
private:
};


int main(int argc, char* argv[])
{
    //A a1, a2;
    //a2 = a1;  //错误:使用了被删除的函数‘A& A::operator=(const A&)’

//    B b1, b2(b1); //:使用了被删除的函数‘B::B(const B&)’
//    b2 = b2;
//
//    C c1, c2;
//    c2 = c1; 
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值