Error:间接寻址级别不同——C++真的魔鬼

今天写程序报错了,上网去查这个错误:
错误 C2040 “remove”:“stu *(stu *)”与“stu *(stu *)”的间接寻址级别不同

查到了一个很让人震惊的点。
这是原楼主的问题

//用强制类型转换可以解决,但我想知道这是为什么错,第一次见到这错误

#include <iostream>
using namespace std;

class test
{
public:
test(int* pi)
{
this->pi=pi;
}
private:
int* pi;

};

int main()
{
int *p = new int (8);
test(p);
}
/*
错误输出:
c:\documents and settings\wengtn\my documents\visual studio 2005\projects\werwer\werwer\weeeeer.cpp(60) : error C2040: “p”: “test”与“int *”的间接寻址级别不同
c:\documents and settings\wengtn\my documents\visual studio 2005\projects\werwer\werwer\weeeeer.cpp(60) : error C2512: “test”: 没有合适的默认构造函数可用
*/

一位老哥的回答:
test.cpp: In function `int main()’:
test.cpp:19: error: conflicting declaration ‘test p’
test.cpp:18: error: ‘p’ has a previous declaration as `int
p’
test.cpp:19: error: declaration of `test p’
test.cpp:18: error: conflicts with previous declaration `int*p’
test.cpp:19: error: no matching function for call to `test::test()’
test.cpp:5: note: candidates are: test::test(const test&)
test.cpp:8: note: test::test(int
)
上面代码用g++编译报上面的错误,g++编译器认为test( p );等价于 test p;当着变量定义了,和前面的定义冲突了。
**

看到这我疑惑了,刚刚学习了与类相关的知识,我也想不通为啥,但这不重要,
然后问问题的老哥回复:

说对了
test(x)和test x是等价的,都是申明变量。
原来()可以用在申明中把变量名包起来,通常申明函数指针的时候会用到,原来用于一般变量也可以这样。
(int*) p 会被编译器认为是一个数据,变量名是绝不可能是这个样子的,所以就用这个数据作为参数构造test对象了,所以强制转换之后不会出错。
C++太神奇了,呵呵!

接下来还有一些分析,就不一一展示,总的来说,也就是test(p)语句这里出现了问题,编译器用这条语句生成了一个test的实例,而非提问者所预想的调用构造函数把p传进形参。因为程序肯定是被截取下来了一部分,所以不完整,我认为提问的人是想要调用定义的构造函数创建一个test的实例。

该语句为什么是生成p对象这一点,我觉得很新奇,因为我看书的时候没见过这么创建对象的,不知道原来还有这么一个处理策略(就知道有类型转换,结果还和问题无关)。但是基于这条处理策略,我们就要想办法抹除该二义性,test((int*)p)是合适的,因为(int*)不可能通过标识符规则那一关,那么编译器就会放弃以此为变量名创建test实例的策略,而进行提问者想要的行为——调用定义的构造函数构建一个无名test实例,以*p的值进行初始化。

因为听说C++细节特别多,见坑不记录下来怕日后被这种问题搅和得睡不着,就记这么多!
值得一提的是,我的问题并没有被解决,我还要去找。

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值