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

时间:2018-03-15 17:36:49

标签: c++ class oop inheritance

提出的问题:

  1. 将以下功能添加到问题5的Shape类:
  2. 两个私有静态成员shapesCreated和shapesDestroyed,分别用于计算已创建和销毁的Shape对象的总数。 析构函数,它增加shapesDestroyed的值 修改类构造函数,以便每次创建新的Shape对象时它都会增加shapesCreated变量。 静态方法static int shapesCount(),返回仍然活动的当前Shape对象数。 将shapeID(非静态)成员添加到Shape类,该类是形状的唯一整数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类中的私有数据成员。但是,尝试在我的派生类构造函数中访问这些是一个问题。基本上它们会随着形状的创建而增加,并且会被破坏。但是,它遇到了我的类中创建和销毁的变量的问题。我已经尝试将这些更改为受保护(问题说明私有)但无济于事。在试图让它正确运行时,我们将非常感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

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

int Shape::shapesCreated = 0;

.cpp文件中执行此操作。

我认为即使你可以直接在课堂内进行整理,但我上面应该可以。