C ++未定义对已继承的受保护类成员的引用[重复]

Posted

技术标签:

【中文标题】C ++未定义对已继承的受保护类成员的引用[重复]【英文标题】:C++ undefined reference to protected class member which has been inherited [duplicate] 【发布时间】:2018-03-15 17:36:48 【问题描述】:

提出的问题:

    将以下特征添加到问题 5 的 Shape 类中:

两个私有静态成员shapeCreated和shapeDestroyed,分别用于统计已创建和销毁的Shape对象的总数。 一个析构函数,它增加了shapesDestroyed的值 修改类构造函数,使其在每次创建新的 Shape 对象时递增 shapeCreated 变量。 一个静态方法 static int shapesCount(),它返回当前仍然存在的 Shape 对象的数量。 向 Shape 类添加一个 shapeID(非静态)成员,这是一个形状的唯一整数 id。使用构造时的shapesCreated值设置它的值,即创建的第n个形状的id值等于n。 添加一个方法 int id() 以返回 Shape 对象的 id。 【15分】

Q7。编写两个继承自 Shape 的类 Circle 和 Rectangle 并正确实现它们的构造函数来设置它们的半径/坐标,视情况而定。他们还必须实现从 Shape 继承的 info() 方法。他们的 info() 方法应该返回一个包含形状 id、形状坐标信息和形状颜色的字符串。

[15 分]

我的代码:

#include <iostream>
#include <sstream>
using namespace std;
int shapeIDCounter = 0,createDestroyCounter=0;

class Colour
    private:
        double red,blue,green;

    public:
        double rMax;


        Colour(double a,double b,double c)
            red = a;
            blue = b;
            green = c;


        
        // #1
        Colour(const Colour& clr)
            red = clr.r();
            blue = clr.b();
            green = clr.g();
            cout << "\nConstructed colour by copying anothers properties";
        

        double r() const 
            return red;
            

        double b() const 
            return blue;
            

        double g() const 
            return green;
            

        string toString()
        string info = "The value for the colour components are: (";
        ostringstream convertR;
        convertR << r();
        info += convertR.str();
        ostringstream convertB;
        info += ",";
        convertB << b();
        info += convertB.str();
        ostringstream convertG;
        info += ",";
        convertG << g();
        info += convertG.str();
        info += ")";
        return info;
        

        static Colour maxRed(Colour carr[], int size)
            double rMax;
            rMax = carr[0].r(); //initial case of first element
            for(int i = 1;i<=size;i++)
                if(carr[i].r() > carr[i-1].r())
                    rMax= carr[i].r();
                
                cout << "\nThe largest Red Value in the array is: " << rMax;

        
;
//the abstract class

class Shape: public Colour

    protected:
    static int shapesCreated;
    static int shapesDestroyed;
    protected:
    int shapeID;




    public:

    Shape(double a,double b,double c):Colour(a,b,c)
        setCreateDestroy(); //used to initialize created & destroyed values
        shapesCreated++;
        shapeIDCounter++;
        shapeID = shapeIDCounter;
    

    void setCreateDestroy()
        if(createDestroyCounter == 0)
        shapesCreated = 0;
        shapesDestroyed = 0;
        createDestroyCounter = 1;
    
    

    virtual string info()=0; //making the class abstract

    ~Shape()
    shapesDestroyed++;
    

    static int shapesCount()
    int shapesAlive = shapesCreated - shapesDestroyed;
    return shapesAlive;

    

    int id()
    return shapeID;
    
;



class Rectangle: public Shape

    private:
    double x1,y1,x2,y2; //co-ordinates of opposite corners

    public:

    Rectangle(double a,double b,double c,double x_1,double y_1,double x_2,double y_2):Shape(a,b,c)
    x1 = x_1;
    x2 = x_2;
    y1 = y_1;
    y2 = y_2;
    

    string info()
    //needs to return the coord's & colour AND SHAPE ID

        string rectInfo = toString();
        rectInfo += "\nThe co-ordinates of the rectangle's opposite corners are (";
        ostringstream convertX1;
        convertX1 << x1;
        rectInfo += ",";
        ostringstream convertY1;
        convertY1 << y1;
        rectInfo += ") and (";
        ostringstream convertX2;
        convertX2 << x2;
        rectInfo += ",";
        ostringstream convertY2;
        convertY2 << y2;
        rectInfo += ")\nThe Shape ID is: \a";
        ostringstream convertID;
        convertID << shapeID;
    return rectInfo;
    

;

class Circle: public Shape

    private:
    double x1,y1,radius; //all relevant coords for circle

    public:

    Circle(double a,double b,double c,double x_1,double y_1,double rad):Shape(a,b,c)
    x1 = x_1;
    y1 = y_1;
    radius = rad;
    cout << "test";
    

    string info()
    string circInfo = toString();
    circInfo += "\nThe co-ordinates of the circles center is (";
    ostringstream convertX1;
    convertX1 << x1;
    circInfo += ",";
    ostringstream convertY1;
    convertY1 << y1;
    circInfo += ")\nThe radius of the circle is: ";
    ostringstream convertRadius;
    convertRadius << radius;
    circInfo += "\nThe Shape ID is: \a";
    ostringstream convertID;
    convertID << shapeID;
    return circInfo;
    
;


int main()

Circle c1(1,1,1,1,1,1);
return 0;

问题:

尝试从我的派生形状类中创建一个 Rectangle 或 Circle 对象。该问题要求shapesDestroyed 和Created 变量是Shape 类中的私有数据成员。但是,尝试在我的派生类构造函数中访问这些被证明是一个问题。基本上,它们将随着形状的创建和形状的破坏而增加。但是,我的班级中创建和销毁的变量遇到了问题。我曾尝试将这些更改为受保护的(尽管问题是私有的)但无济于事。在尝试使其正确运行时,我们将不胜感激。

【问题讨论】:

这和protected无关,都是static 您能否提供现有问题的链接?我在最初搜索时找不到它。 您已经在本页顶部找到了它。出于某种原因,该网站将重复标记分为两部分。 【参考方案1】:

作为类成员的静态变量需要在类之外初始化,如下所示:

int Shape::shapesCreated = 0;

.cpp 文件中执行此操作。

我认为即使您可以直接在 ints 类中执行此操作,但我上面应该可以工作。

【讨论】:

我只能有一个文件?这还能用吗? 如果是你编译的文件,是的,为每个静态变量添加到类之外。 在类内定义适用于const static,而不仅仅是static 在我添加的类之外:static Shape::shapesCreated = 0;静态形状::shapesDestroyed = 0;并删除了我之前用来初始化它们的函数。现在我的错误消息显示为:“int shape::shapesDestroyed 是私有的”在它在类中首次声明的行上。还有:Shape 类中的 shapeDestroyed 没有命名类型。有什么建议吗? 不是一个新问题,但提供的解决方案似乎不起作用:(

以上是关于C ++未定义对已继承的受保护类成员的引用[重复]的主要内容,如果未能解决你的问题,请参考以下文章

未定义的引用,继承问题 - C++ [重复]

C++ 类和继承错误:未定义对派生类的引用

c++类继承,未定义引用'Class::Constructor()'

[C++11 类的改进] --- 继承控制:=default和=delete

静态类成员获得“未定义的引用”。不知道为啥

对静态类成员的未定义引用