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

时间:2016-11-14 10:05:33

标签: c++

我有一个自定义的异常类:

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;
}

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

另一个自定义类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

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;
  }
}

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;
}

编译器给我回错:

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.

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

1 个答案:

答案 0 :(得分:6)

没有“调用构造函数”这样的东西。 <{1}},Exception(errno)(Exception)errno在您的代码中都是等效的。

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

static_cast<Exception>(errno)

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

Exception(int whatever_errno_actually_expands_to);

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