没有空构造函数的编译失败

Compile fails without empty constructor

本文关键字:编译 失败 构造函数      更新时间:2023-10-16

我是C 的新手,并试图准确地了解我的代码正在发生的事情。

这些类都在自己的标头文件中定义。代码在下面。

队列:

template<class T> class Queue
{
  public:
    Queue(unsigned int size)
    {
        _buffer = new T[size]; //need to make sure size is a power of 2
        _write = 0;
        _read = 0;
        _capacity = size;
    }
    
    /* other members ... */
   
   private:
    unsigned int _capacity;
    unsigned int _read;
    unsigned int _write;
    T *_buffer;
};

序列:

template<class T> class Queue;
template<class T> class Serial
{
  public:
    Serial(unsigned int buffer_size)
    {
        _queue = Queue<T>(buffer_size); //<---here is the problem
    }
  private:
    Queue<T> _queue;
};

当我尝试创建这样的串行实例时:

Serial<unsigned char> s = Serial<unsigned char>(123);

编译器抱怨没有零参数的队列构造函数,至少这是我认为错误的含义:

In instantiation of 'Serial<T>::Serial(unsigned int) [with T = unsigned char]':
no matching function for call to 'Queue<unsigned char>::Queue()'
ambiguous overload for 'operator=' in '((Serial<unsigned char>*)this)->Serial<unsigned char>::_queue = (operator new(16u), (((Queue<unsigned char>*)<anonymous>)->Queue<T>::Queue<unsigned char>(buffer_size), ((Queue<unsigned char>*)<anonymous>)))' (operand types are 'Queue<unsigned char>' and 'Queue<unsigned char>*')
invalid user-defined conversion from 'Queue<unsigned char>*' to 'const Queue<unsigned char>&' [-fpermissive]
invalid user-defined conversion from 'Queue<unsigned char>*' to 'Queue<unsigned char>&&' [-fpermissive]
conversion to non-const reference type 'class Queue<unsigned char>&&' from rvalue of type 'Queue<unsigned char>' [-fpermissive]

当我添加一个空的构造函数以排队毫无问题的情况。当我使用调试器逐步完成时,我发现它正在使用参数进入构造函数,而不是空的。

为什么会发生?

Serial(unsigned int buffer_size)缺少成员启动列表,因此必须先使用默认构造函数创建_queue,然后将值(Queue<T>(buffer_size))分配给它。

这个:

Serial(unsigned int buffer_size) : _queue(buffer_size) {}

将使用Queue(unsigned int)构造函数,并且在没有默认构造函数的情况下可以使用。

查看OPS类并查看一系列指针以及在CTOR中使用新的使用时,我会以类似的方式设计类:

队列

#ifndef QUEUE_H
#define QUEUE_H
template<class T>
class Queue {
private:
    size_t size_;
    size_t capacity_;
    size_t read_;
    size_t write_;
    // Either of these depending on case of use or ownership
    std::vector<std::shared_ptr<T>> buffer_;
    std::vector<std::unique_ptr<T>> buffer_;
public:
    Queue() {}
    explicit Queue( size_t size ) : size_(size) {
        buffer_.resize( size_ );
    }   
}; // Queue
#endif // !QUEUE_H

序列

#ifndef SERIAL_H
#define SERIAL_H
template<class T> class Queue;
template<class T> 
class Serial {
private:
    Queue<T> queue_;
public:
    Serial() {}
    explicit Serial( size_t bufferSize ) {
        queue_ = Queue<T>( bufferSize );
    }
}; // Serial
#endif // !SERIAL_H

串行类并不是问题,因为它使用了队列类型的堆栈对象。现在,至于队列对象,由于它正在使用new operator的指针,因此还必须有一个匹配的delete operator,这直接指示驱动器必须管理某种内存资源(S)。

正是由于这种情况,我选择使用vector<smart_ptr>而不是array[size] raw pointers。这有助于防止记忆泄漏,悬挂的指针等。至少要写出这3个以完成Rule of 3

也很重要。
  • Destructor
  • Copy Constructor
  • Assignment Operator

,可能有必要编写这些以完成Rule of 5

  • Move Constructor
  • Move Assignment Operator