-1

我对 C++ 还是有点陌生​​,首先我想为冗长的垃圾代码道歉。

我实际上是在使用多态来计算正方形和其他形状的面积,那么我如何真正利用这种方式动态创建对象呢?这样我实际上可以将所有 3 种不同的形状存储在一个向量中,这样我就可以在此之后进行排序。我也不确定我这样做是否正确..

请多多指教。

Shape2DLink.h

    #ifndef Shape2DLink_H
#define Shape2DLink_H

#include "ShapeTwoD.h"

#include <iostream>
#include <string>
#include <vector>
#include <memory>
using namespace std;

class Shape2DLink:public ShapeTwoD
{
    public:
        int getx();
        int gety();

        double getArea();

        void InputSensor();//allow user to input data
        void StoreData();
        vector<unique_ptr<ShapeTwoD>> objs;
};
#endif

Shape2DLink.cpp

   ShapeTwoD shape2D;
Square square;
Rectangle rect;
Cross cross;
Shape2DLink shape2dlink;

void Shape2DLink::InputSensor()
{
    string shape,type;  

    cout<<endl<<"\n"<<"[ Input sensor data ]"<<endl;


    cout << "Please enter name of shape: " << endl;
        cin >> shape;
        shape2D.setName(shape); 

    cout << "Please enter special type : " << endl;
        cin >> type;
        shape2D.setWarpSpace(type);

    if(shape == "Square")
    {
        square.setSquareCord();
        square.computeArea();
        objs.push_back(new Square(square));
    }
    else if(shape =="Rectangle")
    {
        rect.setRectCord();
        rect.computeArea();
        objs.push_back(new Rectangle(rectangle));
    }
    else if(shape == "Cross")
    {
        cross.setCrossCord();
        cross.computeArea();
        objs.push_back(new Cross(cross));
    }
}

ShapeTwoD.h(父类)

class ShapeTwoD
{
    public:
        string name, warpSpace;
        bool containsWarpSpace;
        int xCord, yCord;

        int xVal, yVal;
        int length, breath;
        double area;
    //public:
        //constructor
        ShapeTwoD();
        ShapeTwoD(string, bool);

        //accessors/set function
        void setName(string);
        void setValues(int, int);
        bool setContainsWarpSpace();
        void setWarpSpace(string);

        //mutator/get function
        string getName();
        bool getContainsWarpSpace();
        string getWarpSpace(); //get value of warpspace

        //methods
        string toString();
        virtual double computeArea();
        bool isPointInShape(int x, int y);
        bool isPointOnShape(int x, int y); 

        int xvalue[4];
        int yvalue[4];
};

ShapeTwoD.cpp

    using namespace std;

ShapeTwoD::ShapeTwoD()
{
    string name = "";
    bool containsWarpSpace = true;
}

ShapeTwoD::ShapeTwoD(string ShapeName, bool warpspace)
{
    name = ShapeName;
    containsWarpSpace = true;
}

void ShapeTwoD::setName(string shapeName)
{
    name=shapeName;
}

string ShapeTwoD::getName()
{
    return name;
}

string ShapeTwoD::toString()
{
    string s;
    return s;
}

void ShapeTwoD::setValues(int a, int b)
{
    length = a;
    breath = b;
}


bool ShapeTwoD::setContainsWarpSpace()
{
    string warp;
    if(warp=="WS")
    containsWarpSpace=true;
    else if(warp=="NS")
    containsWarpSpace=false;    
}


bool ShapeTwoD::getContainsWarpSpace()
{
   return containsWarpSpace;
}

void ShapeTwoD::setWarpSpace(string space)
{
    warpSpace=space;
}

string ShapeTwoD::getWarpSpace()
{
    return warpSpace;
}


double ShapeTwoD::computeArea()
{

    return area=0.00;
}
bool ShapeTwoD::isPointInShape(int x,int y)
{
    xCord = x;
    yCord = y;

    if(xCord > 5 || yCord > 5)
    {
        return false;
    }
    else
    {
        return true;
    }
}

bool ShapeTwoD::isPointOnShape(int x,int y)
{
    xCord = x;
    yCord = y;

   if(xCord > 10 || yCord <10)
    {
        return false;
    }
    else
    {
        return true;
    }
}

正方形.cpp

Square::Square()
{
    xVal = 0;
    yVal = 0;
}

Square::Square(string ShapeName, bool warpspace, int xval, int yval):ShapeTwoD(ShapeName, warpspace), xVal(xval), yVal(yval)
{
    xVal = xval;
    yVal = yval;
}

void Square::setSquareCord()
{
    for (int i=0; i<4; i++)
    {
        cout << "Please enter x-ordinate of pt " << i+1 << ": "; 
        cin >> xVal;
        xvalue[i] = xVal;
        cout << endl;
        cout << "Please enter y-ordinate of pt " << i+1 << ": ";
        cin >> yVal;
        yvalue[i] = yVal;
        cout << endl;
    }
}


double Square::computeArea()
{
    int xmax = xvalue[1];
    int xmin = xvalue[1];

    int ymax = yvalue[1];
    int ymin = yvalue[1];

    for(int i=0; i<4; i++)
    {
        if(xvalue[i]>xmax)
        {
            xmax = xvalue[i];
        }
        else if(xvalue[i]<xmin)
        {
            xmin = xvalue[i];
        }
    }

    for(int i=0; i<4; i++)
    {
        if(yvalue[i]>ymax)
        {
            ymax = yvalue[i];
        }
        else if(yvalue[i]<ymin)
        {
            ymin = yvalue[i];
        }
    }
    length = xmax - xmin;
    breath = ymax - ymin;

    area = length * breath;

    return (area);
}

矩形.h

class Rectangle:public ShapeTwoD
{
    private:
        int xVal,yVal;
        int length, breath;
        double area;

    public:
        Rectangle();
        Rectangle(string, bool, int, int);

        //mutator method
        //void setRectDetails(int x, int y);
        void setRectCord();

        //acessor method
        //int getRectDetails();
        int getxCord();
        int getyCord();

        bool isPointInShape(int x, int y);
        bool isPointOnShape(int x, int y);

        string toString();
        double computeArea();

        int xvalue[4];
        int yvalue[4];
};

矩形.cpp

Rectangle::Rectangle()
{
    xVal = 0;
    yVal = 0;
}

Rectangle::Rectangle(string ShapeName, bool warpspace, int xval, int yval):ShapeTwoD(ShapeName, warpspace), xVal(xval), yVal(yval)
{
    xVal = xval;
    yVal = yval;
}

void Rectangle::setRectCord()
{
    for (int i=0; i<4; i++)
    {
        cout << "Please enter x-ordinate of pt " << i+1 << ": "; 
        cin >> xVal;
        xvalue[i] = xVal;
        cout << endl;
        cout << "Please enter y-ordinate of pt " << i+1 << ": ";
        cin >> yVal;
        yvalue[i] = yVal;
        cout << endl;
    }
}


double Rectangle::computeArea()
{
    int xmax = xvalue[1];
    int xmin = xvalue[1];

    int ymax = yvalue[1];
    int ymin = yvalue[1];

    for(int i=0; i<4; i++)
    {
        if(xvalue[i]>xmax)
        {
            xmax = xvalue[i];
        }
        else if(xvalue[i]<xmin)
        {
            xmin = xvalue[i];
        }
    }

    for(int i=0; i<4; i++)
    {
        if(yvalue[i]>ymax)
        {
            ymax = yvalue[i];
        }
        else if(yvalue[i]<ymin)
        {
            ymin = yvalue[i];
        }
    }
    length = xmax - xmin;
    breath = ymax - ymin;

    area = length * breath;

    return (area);
}

int Rectangle::getxCord()
{
    return xVal;
}

int Rectangle::getyCord()
{
    return yVal;
}

string Rectangle::toString()
{
  string s;

  int xord = getxCord();
  int yord = getyCord();

  stringstream convertX;
  convertX << xord;

  stringstream convertY;
  convertY << yord;

  string xResult = convertX.str();
  string yResult = convertY.str();

  s += "Coordinate is: " + xResult + "";
  s += "," + yResult + "\n";

  return s;
}

bool Rectangle::isPointOnShape(int x,int y)
{
    x = getxCord();
    y = getyCord();

    if(x > 3 || y > 3)
    {
        return true;
    }
    else
    {
        return false;
    }

}

bool Rectangle::isPointInShape(int x,int y)
{
    x = getxCord();
    y = getyCord();

    if(x > 5|| y >5)
    {
        return false;
    }
    else
    {
        return true;
    }
}

交叉.h

    class Cross:public ShapeTwoD
    {
        private:
            int xVal,yVal;
            int length, breath;
            double area;

        public:
            Cross();
            Cross(string, bool, int, int);

            //mutator method
            //void setSquareDetails(int x, int y);
            void setCrossCord();

            //acessor method
            //int getSquareDetails();
            int getxCord();
            int getyCord();

            bool isPointInShape(int x, int y);
            bool isPointOnShape(int x, int y);

            string toString();
            double computeArea();

            int xvalue[12];
            int yvalue[12];


    };

cross.cpp

Cross::Cross()
{
    xVal = 0;
    yVal = 0;
}

Cross::Cross(string ShapeName, bool warpspace, int xval, int yval):ShapeTwoD(ShapeName, warpspace), xVal(xval), yVal(yval)
{
    xVal = xval;
    yVal = yval;
}

void Cross::setCrossCord()
{
    for (int j=0; j<12; j++)
    {
        cout << "Please enter x-ordinate of pt " << j+1 << ": "; 
        cin >> xVal;
        xvalue[j] = xVal;
        cout << endl;
        cout << "Please enter y-ordinate of pt " << j+1 << ": ";
        cin >> yVal;
        yvalue[j] = yVal;
        cout << endl;
    }
}


double Cross::computeArea()
{
    int points = 12;
    int running_total =0;
    int i;
    running_total = 0;
    for (i=0; i<points-1; i++)
    {
      running_total += xvalue[i]*yvalue[i+1] - xvalue[i+1]*yvalue[i]; //cross calculation of coord in a cross 
    }                                                                 //(x1*y2)-(y1*x1)

    running_total += xvalue[points-1]*yvalue[0] - xvalue[0]*yvalue[points-1];   // traverse back to the origin point (xn*y1)-(yn*x1)
    area = abs(running_total / 2); //purpose of absolute is to make sure result is positive. 
                                  //polygon are specified in counter-clockwise order (i.e. by the right-hand rule), then the area will be positive.
    //cout << area;
    return (area);
}

int Cross::getxCord()
{
    return xVal;
}

int Cross::getyCord()
{
    return yVal;
}

string Cross::toString()
{
  string s;

  int xord = getxCord();
  int yord = getyCord();

  stringstream convertX;
  convertX << xord;

  stringstream convertY;
  convertY << yord;

  string xResult = convertX.str();
  string yResult = convertY.str();

  s += "Coordinate is: " + xResult + "";
  s += "," + yResult + "\n";

  return s;
}

bool Cross::isPointOnShape(int x,int y)
{
    x = getxCord();
    y = getyCord();

    if(x > 3 || y > 3)
    {
        return true;
    }
    else
    {
        return false;
    }

}

bool Cross::isPointInShape(int x,int y)
{
    x = getxCord();
    y = getyCord();

    if(x > 5|| y >5)
    {
        return false;
    }
    else
    {
        return true;
    }
}
4

2 回答 2

2

这样的事情应该会有所帮助:

if(shape == "Square")
{
    Square* new_square;
    objs.emplace_back(new_square = new Square());
    new_square->setSquareCoord();
    new_square->computeArea();
}

然后改变

vector<ShapeTwoD*> objs;

vector<std::unique_ptr<ShapeTwoD>> objs;

这样当它们的指针从向量中删除时,对象将被正确删除。

于 2013-11-03T18:32:13.163 回答
0

您的代码有很多问题,其中大部分因您未能提供变量定义等而使我们难以理解。但是,似乎square(在 的主体中Shape2DLink::InputSensor())是一个对象,可能是 type Square,尽管它在哪里定义仍然很神秘(它不是自动变量,也不是Shape2DLink) 的成员。除非您已明确定义它,否则*square没有意义并且编译器会报告错误。如果square是指针,那么*square将是(对)指向的对象。

我想你想给你的objs. 这可以通过

objs.push_back(new Square);                 // calls default constructor for Square
objs.push_back(new Square(other_square));   // calls copy constructor
objs.push_back(new Square(parameters));     // calls some other constructor

在正确的代码中,你会

1具有Square将所有成员数据设置为适当值的构造函数。此外,如果您考虑在Square其整个生命周期内保留这些值,您应该让它们成为public const成员。

2使用std::unique_ptr<ShapeTwoD>std::shared_ptr<ShapeTwoD>管理对象的生命周期,查看它们的文档

于 2013-11-03T18:31:54.703 回答