类类型转换失败C ++

时间:2015-06-10 16:42:06

标签: c++ type-conversion incomplete-type

我正在尝试编写一些东西,但它不会,我在网上找不到任何相关内容。

#include<iostream>
using namespace std;

class A;
class B
{
    int x;
public:
    B(int i=107) {x=i;}
    operator A();
};
B::operator A() {return x;}

class A
{
    int x;
public:
    A(int i=6) {x=i;}
    int get_x() {return x;}
};

int main()
{
    A a;
    B b=a;
    cout<<a.get_x();
    return 0;
}

我收到错误: 返回类型“A类”不完整 从'A'转换为非标量类型'B'请求

这甚至不起作用:

    B B;
    A a=b;

我不知道我做错了什么,而且我不知道在哪里可以找到关于这个主题的更多信息。

谢谢

3 个答案:

答案 0 :(得分:3)

您没有发布错误的全文,这意味着您遗漏了所有重要的行号。通常情况下,行号通常是错误中最有价值的信息。

class A;
class B
{
    ...
};
B::operator A() {return x;}

我猜这是你的编译器告诉你错误发生的行。

在这行代码中,编译器还没有A的完整声明,所以它不知道如何将int x转换为class A。 C ++编译是单次传递,因此不能推迟查找。

在继续定义之前,您需要完成声明。

class A;
class B
{
    int x;
public:
    B(int i=107) {x=i;}
    operator A();
};

class A
{
    int x;
public:
    A(int i=6) {x=i;}
    int get_x() {return x;}
};

// done with declarations. begin definitions.

B::operator A() {return x;}
// compiler quietly expands this to be:
// B::operator A() { return A::A(i=this->x); }

通常,AB将位于头文件中,您将保留定义,这需要完全声明两个类,以及.cpp文件。

答案 1 :(得分:1)

您可以轻松地将B类声明移到A类声明之下。

class A
{
    ...
};

class B
{
    ...
    operator A();
};
B::operator A() {return x;}

并且不使用前向声明。然后像这样使用运算符,因为你没有将A转换为B,而是将B转换为A.

B b;
A a = b; // A a = (A)b;
...

关于会发生什么我添加了一些打印来显示代码通过的地方,

A(int i=6) {
    std::cout<<"Created A"<<std::endl;x=i;
}
A( const A& a ) {
    std::cout<<"Created A by Copy"<<std::endl;
    this->x = a.x;
}
B::operator A() {
    std::cout << "Operator A" << std::endl;
    return x;
}

跑了这个,

B b;
std::cout << "Begin" << std::endl;
A a = b;
std::cout << "End" << std::endl;
...

这是输出,

Begin
Operator A
Created A
Created A by copy
End

因此,运算符A返回一个int,用于构造A的实例,然后用于通过复制初始化实例'a'。我从来不知道你可以做这些事情(你可能不想这样做,但是是啊..)

编辑:您实际应该在运算符A()中显式创建A实例,而不是依赖于编译器。

答案 2 :(得分:1)

代码有几个问题(参见评论)

#include<iostream>

// Side Note: Never do this in a header (I avoid it in sources, too)
using namespace std;

class A;
class B
{
    int x;
public:
    B(int i=107) {x=i;}
    operator A() const;
    // Moved to make 'main' reasonable
    int get_x() {return x;}
};

class A
{
    int x;
public:
    A(int i=6) {x=i;}
    // Make the desired conversion work:
    operator B () const { return x; }
};

// This nedds a complete A. In other words, the delaration of A has to be knonwn.
B::operator A() const {return x;}


int main()
{
    A a;
    B b=a;
    cout << b.get_x() << '\n';
    return 0;
}