简体   繁体   English

C ++中的转换构造函数

[英]Conversion Constructor in C++

Program below is giving error 'invalid use of incomplete type class Rectangle' and 'forward declaration of class Rectangle'. 下面的程序给出错误“无效使用不完整类型的类Rectangle”和“正向声明类Rectangle”。 How to fix this without editing any header file? 如何在不编辑任何头文件的情况下解决此问题? Isn't there any possible way to do the conversion using constructor only? 没有任何可能的方法仅使用构造函数进行转换吗?

include<iostream>
include<math.h>

using namespace std;

class Rectangle;
class Polar
{
    int radius, angle;

public:
    Polar()
    {
        radius = 0;
        angle = 0;
    }

    Polar(Rectangle r)
    {
        radius = sqrt((r.x*r.x) + (r.y*r.y));
        angle = atan(r.y/r.x);
    }

    void getData()
    {
        cout<<"ENTER RADIUS: ";
        cin>>radius;
        cout<<"ENTER ANGLE (in Radians): ";
        cin>>angle;
        angle = angle * (180/3.1415926);
    }

    void showData()
    {
        cout<<"CONVERTED DATA:"<<endl;
        cout<<"\tRADIUS: "<<radius<<"\n\tANGLE: "<<angle;

    }

    friend Rectangle :: Rectangle(Polar P);
};

class Rectangle
{
    int x, y;
public:
    Rectangle()
    {
        x = 0;
        y = 0;
    }

    Rectangle(Polar p)
    {
        x = (p.radius) * cos(p.angle);
        y = (p.radius) * sin(p.angle);
    }

    void getData()
    {
        cout<<"ENTER X: ";
        cin>>x;
        cout<<"ENTER Y: ";
        cin>>y;
    }

    void showData()
    {
        cout<<"CONVERTED DATA:"<<endl;
        cout<<"\tX: "<<x<<"\n\tY: "<<y;
    }

    friend Polar(Rectangle r);


};

You're trying to access the incomplete type Rectangle in your Polar(Rectangle) constructor. 您正在尝试在Polar(Rectangle)构造函数中访问不完整的Rectangle类型。

Since the definition of the Rectangle constructor also needs the complete definition of Polar , you'll need to separate the class definition from the constructor definition. 由于Rectangle构造函数的定义也需要Polar的完整定义,因此您需要将类定义与构造函数定义分开。

Solution: Put the definitions of your member functions in a .cpp file, as you should be doing, like this: 解决方案:像您应该做的那样,将成员函数的定义放在.cpp文件中,如下所示:

polar.h: polar.h:

class Rectangle; // forward declaration to be able to reference Rectangle

class Polar
{
    int radius, angle;
public:
    Polar() : radius(0), angle(0) {} // initializes both members to 0
    Polar(Rectangle r); // don't define this here
    ...
};

polar.cpp: polar.cpp:

#include "polar.h"
#include "rectangle.h" // to be able to use Rectangle r

Polar::Polar(Rectangle r) // define Polar(Rectangle)
:   radius(sqrt((r.x*r.x) + (r.y*r.y))),
    angle(atan(r.y/r.x))
{
}

The above initializes radius and angle to what's inside the brackets. 上面的代码将radiusangle初始化radius方括号内的内容。

rectangle.h: 矩形.h:

class Polar; // forward declaration to be able to reference Polar

class Rectangle
{
    int x, y;
public:
    Rectangle() : x(0), y(0) {} // initializes both x and y to 0
    Rectangle(Polar p); // don't define this here
    ...
};

rectangle.cpp: 矩形.cpp:

#include "rectangle.h"
#include "polar.h" // to be able to use Polar p

Rectangle::Rectangle(Polar p) // define Rectangle(Polar)
:   x((p.radius) * cos(p.angle)),
    y((p.radius) * sin(p.angle))
{
}

I also showed you how to use constructor initialization lists which you should be using in C++ to initialize member variables. 我还向您展示了如何使用构造函数初始化列表 ,您应该在C ++中使用该列表来初始化成员变量。

How to fix this without editing any header file. 如何在不编辑任何头文件的情况下解决此问题。

You can't. 你不能 The definition of Polar(Rectangle) will have to come after the definition of Rectangle , so that Rectangle is complete where the constructor needs to use it. Polar(Rectangle)的定义必须在Rectangle的定义之后,以便Rectangle在需要构造函数使用的地方完整。

Just declare the constructor in the class definition: 只需在类定义中声明构造函数:

Polar(Rectangle r);

and define it elsewhere; 并在其他地方定义它; either in a source file, or in a header after defining Rectangle (in which case you'll need to mark it inline ). 要么在源文件中,要么在定义Rectangle之后的标头中(在这种情况下,您需要将其标记为inline )。

Personally, I'd tidy this up by splitting it into two headers, one per class, and defining all the members in source files (unless I've proved that they need to be inline for performance reasons). 就个人而言,我会通过将其拆分为两个标头(每个类一个)并定义源文件中的所有成员(除非出于性能原因已证明它们必须是内联的)的方式进行整理。 Then the headers will each only need to declare the other class, and only need to be included from the source files that implement or use the classes. 然后,每个标头仅需要声明另一个类,并且仅需要从实现或使用这些类的源文件中包含这些标头。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM