什么叫“间接寻址级别不同”,这异常什么意思。麻烦老大们帮忙解释下
什么叫“间接寻址级别不同”,这错误什么意思。麻烦老大们帮忙解释下。
用强制类型转换可以解决,但我想知道这是为什么错,第一次见到这错误
#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(p)是调用的一个函数,而test实际是一个类。所以报错。
如果你改成 test a(p)就不会有问题了。
------解决方案--------------------
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;当着变量定义了,和前面的定义冲突了。
------解决方案--------------------
gfxiang(afu)和jamesfancy(边城狂人) 正解
补充解释一下这两个错:
error C2040: “p”: “test”与“int *”的间接寻址级别不同
error C2512: “test”: 没有合适的默认构造函数可用
单纯的语句 test(p); 将定义一个test类实例p,相当于 test p; 但test并没有定义默认构造函数,所以有了第二个错。另因为p以声明为int*类型,而test(p)语句试图把生成的test实例转换为int*类型,这就引发了第一个错,因为一个test实例和一个指针有着不同的寻址级(different levels of indirection)。
test((int* p))将会通过编译,是因为这里(int* p)被解析为构造函数的参数,而非新test实例的名称。这句语句在运行时将生成一个无名test实例,其pi被初始化为p;因为无名,该实例不可访问,所以纯粹无用。
这里g++和vs2005两个编译器报不同的错误是似乎是因为两者解析的顺序的不同。在vs2005里修正了第一个错误后,以如下语句编译,将会得到和g++同样的报错。
int p=9;
test(p);//error C2371: 'p ' : redefinition; different basic types
------解决方案--------------------
相关标准:
6.8 Ambiguity resolution [stmt.ambig]
1 There is an ambiguity in the grammar involving expression-statements and declarations: An expression-statement with
a function-style explicit type conversion (5.2.3) as its leftmost subexpression can be indistinguishable from a declaration
where the first declarator starts with a (. In those cases the statement is a declaration. [ Note: To disambiguate, the whole
statement might have to be examined to determine if it is an expression-statement or a declaration. This disambiguates
many examples. [ Example: assuming T is a simple-type-specifier (7.1.5),
T(a)-> m = 7; / / expression-statement
T(a )++; / / expression-statement
T(a ,5) < <c; / / expression-statement
T(*d)( int ); / / declaration
T(e )[5]; / / declaration
T(f ) = { 1 , 2 }; / / declaration
T(*g)( double (3)); / / declaration
In the last example above, g, which is a pointer to T, is initialized to double(3). This is of course ill-formed for
semantic reasons, but that does not affect the syntactic analysis. —end example ]
一言以蔽之,能作为声明的语句就被认作是声明, 所以这里test(p)背认定为声明而不是构造一个临时的test变量。
“test(p)语句试图把生成的test实例转换为int*类型,”这里不存在“实例类型转换“的问题,int*类型的实例是可以转换为test实例的,可能vc6.0在声明和定义之间做出错误或是过晚的抉择造成的。
用强制类型转换可以解决,但我想知道这是为什么错,第一次见到这错误
#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(p)是调用的一个函数,而test实际是一个类。所以报错。
如果你改成 test a(p)就不会有问题了。
------解决方案--------------------
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;当着变量定义了,和前面的定义冲突了。
------解决方案--------------------
gfxiang(afu)和jamesfancy(边城狂人) 正解
补充解释一下这两个错:
error C2040: “p”: “test”与“int *”的间接寻址级别不同
error C2512: “test”: 没有合适的默认构造函数可用
单纯的语句 test(p); 将定义一个test类实例p,相当于 test p; 但test并没有定义默认构造函数,所以有了第二个错。另因为p以声明为int*类型,而test(p)语句试图把生成的test实例转换为int*类型,这就引发了第一个错,因为一个test实例和一个指针有着不同的寻址级(different levels of indirection)。
test((int* p))将会通过编译,是因为这里(int* p)被解析为构造函数的参数,而非新test实例的名称。这句语句在运行时将生成一个无名test实例,其pi被初始化为p;因为无名,该实例不可访问,所以纯粹无用。
这里g++和vs2005两个编译器报不同的错误是似乎是因为两者解析的顺序的不同。在vs2005里修正了第一个错误后,以如下语句编译,将会得到和g++同样的报错。
int p=9;
test(p);//error C2371: 'p ' : redefinition; different basic types
------解决方案--------------------
相关标准:
6.8 Ambiguity resolution [stmt.ambig]
1 There is an ambiguity in the grammar involving expression-statements and declarations: An expression-statement with
a function-style explicit type conversion (5.2.3) as its leftmost subexpression can be indistinguishable from a declaration
where the first declarator starts with a (. In those cases the statement is a declaration. [ Note: To disambiguate, the whole
statement might have to be examined to determine if it is an expression-statement or a declaration. This disambiguates
many examples. [ Example: assuming T is a simple-type-specifier (7.1.5),
T(a)-> m = 7; / / expression-statement
T(a )++; / / expression-statement
T(a ,5) < <c; / / expression-statement
T(*d)( int ); / / declaration
T(e )[5]; / / declaration
T(f ) = { 1 , 2 }; / / declaration
T(*g)( double (3)); / / declaration
In the last example above, g, which is a pointer to T, is initialized to double(3). This is of course ill-formed for
semantic reasons, but that does not affect the syntactic analysis. —end example ]
一言以蔽之,能作为声明的语句就被认作是声明, 所以这里test(p)背认定为声明而不是构造一个临时的test变量。
“test(p)语句试图把生成的test实例转换为int*类型,”这里不存在“实例类型转换“的问题,int*类型的实例是可以转换为test实例的,可能vc6.0在声明和定义之间做出错误或是过晚的抉择造成的。