我有一个自定义的异常类:
异常.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;
}
异常.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 提供了逐字节反转缓冲区内容的功能:
缓冲区.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
缓冲区.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;
}
}
主.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);
。我在那里调用了构造函数,为什么它被视为类型转换?
最佳答案
没有“调用构造函数”这样的东西。 Exception(errno)
, (Exception)errno
和 static_cast<Exception>(errno)
在您的代码中都是等价的。
话虽这么说,问题的根源是别的:您使用的是保留名称 errno
,这是一个标准宏(具有实现定义的内容)。宏不考虑 C++ 作用域,所以你的构造函数声明实际上是
Exception(int whatever_errno_actually_expands_to);
在我的 gcc 上,这实际上是:
Exception(int (*__errno_location ()));
解决方案:不要使用标识符的保留名称。
关于c++ - 强制调用构造函数而不是函数式转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40586110/