2

我正在设计一些类来访问和控制微控制器的外围设备(adc、端口、usart 等)。该设备只有几个(在某些情况下只有一个)每个外围设备的实例,因此我决定将每个外围设备表示为一个单态类。我的一个类的定义和用法是这样的:

usart.h

class usart {
public:
    static void init() { /* initialize the peripheral */ } 
    static char read() { /* read a char from the input buffer */ }
    static void write(char ch) { /* write a char to the output buffer */ }
    // ... more member functions
};

main1.cpp

#include "usart.h"

int main()
{
    usart::init();

    char data;
    while (true) {
        data = usart::read();
        usart::write(data);
    }

}

但是上面定义 usart 类的方式并没有禁止用户做这样的事情:

main2.cpp

#include "usart.h"

int main() 
{
    // I don't want object construction
    usart serial1;
    usart serial2;

    // neither assignment
    serial1 = serial2;

    // two objects representing the same hardware resource
    // I don't want that
    serial1.init();
    serial2.write('r');
}

我知道从 C++11 开始我可以使用delete关键字来防止编译器创建默认构造函数和函数,但我不知道编译器创建的这些默认值到底是什么。有复制构造函数、复制赋值、移动语义重载等。我需要在我的类上放置多少个delete (以及在哪些函数和构造函数中)?

更新:我知道我可以(也许应该)使用命名空间而不是类,但恐怕以后我需要将这些类(或命名空间)作为模板参数传递。AFAIK 不可能使用命名空间作为模板参数,因为我选择使用具有静态成员的类而不是命名空间。

4

2 回答 2

4
struct cannot_exist {
  cannot_exist()=delete;
  ~cannot_exist()=delete;
  cannot_exist(cannot_exist const&)=delete;
  cannot_exist(cannot_exist &&)=delete;
  cannot_exist& operator=(cannot_exist const&)=delete;
  cannot_exist& operator=(cannot_exist &&)=delete;
};

这是一个类,其中 C++ 为您生成的每个成员都被显式删除。(你可以用更少的东西来做到这一点,但我认为这一点不那么明确)。

简单地继承cannot_exist和......你的类的实例不能存在,也不会有编译器自动定义的任何成员函数。尝试调用它们会产生编译器错误。

但是,一旦您有一个不存在的类,请考虑使用namespace.

class usart:cannot_exist {
public:
  static void init() { /* initialize the peripheral */ } 
  static char read() { /* read a char from the input buffer */ }
  static void write(char ch) { /* write a char to the output buffer */ }
  // ... more member functions
};

对比

namespace usart {
  static void init() { /* initialize the peripheral */ } 
  static char read() { /* read a char from the input buffer */ }
  static void write(char ch) { /* write a char to the output buffer */ }
  // ... more member functions
};
于 2017-07-20T14:51:14.513 回答
0

我会尝试这两种方法

  1. 在类中声明一个纯虚函数。这使得类是纯虚拟的,所以它不能被实例化。

  2. 将默认构造函数声明为私有成员函数。这样,没有外部类方法可以访问构造函数。

于 2017-07-20T14:47:28.800 回答