强制调用构造函数而不是函数式的强制转换

JAC*_*K M 0 c++

我有一个自定义的Exception类:

Exception.cc:

#include "Exception.h"


const char* Exception::getMessage()
{
  return strerror(this -> error_code);
}

int Exception::getErrno()
{
  return this -> error_code;
}

Exception::Exception(int errno)
{
  this -> error_code = errno;
}
Run Code Online (Sandbox Code Playgroud)

Exception.hh

#ifndef __EXECPTION_H__
#define __EXECPTION_H__

#include <string.h>

class Exception
{
private:
  int error_code;

public:

    const char* getMessage();

    int getErrno();

  Exception(int errno);
};

#endif
Run Code Online (Sandbox Code Playgroud)

另一个自定义类Buffer,它提供一个逐字节反转缓冲区内容的函数:

Buffer.h:

#ifndef __BUFFER_H__
#define __BUFFER_H__

#include <stdlib.h>
#include <cerrno>

class Buffer
{

private:
  char * buffer;
  int size;


public:
    Buffer(int size);
  ~Buffer();
  void reverse();

    friend class File;
};

#endif
Run Code Online (Sandbox Code Playgroud)

Buffer.cc:

#include "Buffer.h"
#include "Exception.h"


Buffer::Buffer(int size)
{
  this -> size = size;
  this -> buffer = (char *)malloc(size);
  if(this -> buffer == NULL)
    throw Exception(errno);
}

Buffer::~Buffer()
{
  if(this -> buffer == NULL)
    free(this -> buffer);
}

void Buffer::reverse()
{
  char tmp;
  int i;
  char * tmpb = this -> buffer;
  for(i = 0; i < this -> size / 2; i++)
  {
    tmp = (char)tmpb[i];
    tmpb[i] = tmpb[size - i - 1];
    tmpb[size - i - 1] = tmp;
  }
}
Run Code Online (Sandbox Code Playgroud)

main.cc

#include "Buffer.h"
#include "Exception.h"
#include <stdlib.h>

#include <iostream>
using namespace std;

int main (const int argc, const char** argv)
{
    if(argc != 3)
    exit(-1);


  return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译器给我回错:

Buffer.cc:10:11: error: no matching conversion for functional-style cast from 'int' to 'Exception'
    throw Exception(errno);
          ^~~~~~~~~~~~~~~
./Exception.h:6:7: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'int' to 'const Exception' for 1st
      argument
class Exception
      ^
./Exception.h:17:3: note: candidate constructor not viable: no known conversion from 'int' to 'int (*(*)())' for 1st argument
  Exception(int errno);
  ^
1 error generated.
Run Code Online (Sandbox Code Playgroud)

看起来编译器误解了throw Exception(errno);.我在那里调用一个构造函数,为什么它被视为类型转换?

krz*_*zaq 6

没有"调用构造函数"这样的东西.Exception(errno),(Exception)errno并且static_cast<Exception>(errno)在您的代码中都是等效的.

话虽这么说,你的问题的根源是别的:你正在使用保留名称errno,这是一个标准的宏(具有实现定义的内容).宏不考虑C++范围,因此实际上是构造函数声明

Exception(int whatever_errno_actually_expands_to);
Run Code Online (Sandbox Code Playgroud)

在我的gcc上,这实际上是:

Exception(int (*__errno_location ()));
Run Code Online (Sandbox Code Playgroud)

解决方案:不要为标识符使用保留名称.