简体   繁体   English

编写此代码的更有效方法是什么?

[英]What's a more efficient way to write this code?

So, I'm a newbie in C++ and I'm trying to learn about inheritance. 所以,我是C ++的新手,我正在尝试学习继承。 I wrote out a program that just simply prints out the perimeter of different shapes, namely a square and a triangle. 我写了一个程序,仅打印出不同形状的周长,即正方形和三角形。 Unfortunately, the way I'm doing it ends up with some duplicated code. 不幸的是,我这样做的方式最终得到了一些重复的代码。 Here's what I mean: 这就是我的意思:

#include <iostream>

class Shape {
public:
  int sides;
  int sideLength;
};

class Square : public Shape {
public:
  int sides = 4;
  int sideLength = 6;
  void calculatePerimeter() {
    int perimeter = sideLength * sides;
    std::cout << "perimeter length: " << perimeter << std::endl;
  }
};

class Triangle : public Shape {
public:
  int sides = 3;
  int sideLength = 4;
  void calculatePerimeter() {
    int perimeter = sideLength * sides;
    std::cout << "perimeter length: " << perimeter << std::endl;
  }
};

int main() {
  Square s;
  std::cout << "number of sides a square has: " << s.sides << std::endl;

  Triangle t;
  std::cout << "number of sides a triangle has: " << t.sides << std::endl;

  s.calculatePerimeter();
  t.calculatePerimeter();
}

As you can see, the calculatePerimeter function is being used in the Square and the Triangle classes. 如您所见,Square和Triangle类中使用了calculatePerimeter函数。 Putting it in the Shape class and calling it resulted in an output of 0. How can I make this more efficient so I don't have to copy/paste it for every shape class I make? 将其放在Shape类中并调用它会导致输出0。如何提高此效率,所以不必为我制作的每个Shape类都复制/粘贴它?

When you use inheritance, you factor common behavior and state in the base class and make derived classes extend this state and behavior with their specific functionality. 使用继承时,可以在基类中考虑常见的行为和状态,并使派生类通过其特定功能扩展此状态和行为。

  1. Remove the sides and sideLength members from Shape. 从Shape中删除side和sideLength成员。 Instead, provide virtual functions in class Shape that return those values, and have the derived classes override them. 而是在Shape类中提供返回这些值的虚拟函数,并使派生类覆盖它们。

  2. Move method calculate perimeter to class Shape, and implement it using the getSides() and getSideLength() Move方法将周长计算为Shape类,并使用getSides()和getSideLength()实现

     #include <iostream> class Shape { public: virtual int getSides() = 0; virtual int getSideLength() = 0; void calculatePerimeter() { int perimeter = getSideLength() * getSides(); std::cout << "perimeter length: " << perimeter << std::endl; } }; class Square : public Shape { public: virtual int getSides() { return 4; } virtual int getSideLength() { return 6; } }; class Triangle : public Shape { public: virtual int getSides() { return 3; } virtual int getSideLength() { return 4; } }; 

This is what is known as a Template Method design pattern (not to be confused with the template function concept of C++, which is an entirely unrelated concept specific to this language). 这就是所谓的模板方法设计模式(不要与C ++的模板函数概念混淆,C ++是与该语言完全无关的概念)。

You need a constructor for Shape and to pass the variables through from the derived constructors. 您需要Shape的构造函数,并从派生的构造函数传递变量。 Then you can move calculatePerimiter into the parent class. 然后,您可以将calculatePerimiter移到父类中。

class Shape {
public:
  Shape(int n_sides, int side_length) : sides(n_sides), sideLength(side_length) {}

  void calculatePerimeter() {
    int perimeter = sideLength * sides;
    std::cout << "perimeter length: " << perimeter << std::endl;
  }

  int sides;
  int sideLength;
};

class Square : public Shape {
public:
  Square() : Shape(4,6) {}     
};

class Triangle : public Shape {
public:
  Triangle() : Shape(3, 4) {}
};

This code: 这段代码:

int sides = 3; int sideLength = 4;

is creating new variables with a local scope view. 正在使用本地范围视图创建新变量。 Without running your code, I would imagine if you simply got rid of the 'int' in front of both lines should fix your problem. 如果不运行代码,我想如果您只是摆脱两行前面的“ int”,就可以解决您的问题。

Edit: put them into a constructor of course. 编辑:当然将它们放入构造函数中。

Edit: Ok, combining code... 编辑:好的,结合代码...

    class Triangle : public Shape {
public:

  Triangle ()
  {
    sides = 3;
    sideLength = 4;
  }

  void calculatePerimeter() {
    int perimeter = sideLength * sides;
    std::cout << "perimeter length: " << perimeter << std::endl;
  }
};

Depending what it is you are trying to understand, the other answers are better solutions to the problem. 根据您要理解的内容,其他答案可以更好地解决问题。 This is simple enough to just put parameters into the calcualatePerimeter() method, but that of course does not test your understanding of variables within a scope, which seemed to be your stumbling block. 这很简单,只需将参数放入calcualatePerimeter()方法即可,但是当然,这不会测试您对范围内变量的理解,这似乎是您的绊脚石。

You can acess immediate base class members and also initialise them. 您可以访问直接基类成员,也可以对其进行初始化。

class Shape {
public:
  int sides;
  int sideLength;
  Shape(int m,int n)
  {
      sides =m;
     sideLength = n;
  }
};

class Square : public Shape {
public:
  Square(int j,int k);

  int calculatePerimeter() {
    int perimeter = sides * sideLength ;
    std::cout << "perimeter length: " << perimeter << std::endl;
    return perimeter;
  }
};

Square::Square(int j,int k):Shape(j,k)
{


}

This would be my approach for a compiler that supports C++11... 对于支持C ++ 11的编译器,这将是我的方法。

#include <iostream>
#include <string>
#include <vector>

using namespace std;

template<class Seq>
void purge(Seq& s) {
    for (auto x: s) {
        delete x;
        x = nullptr;
    }
}

class Shape {
public: 
    virtual void calculatePerimeter() = 0; // to avoid object slicing
    virtual ~Shape() {};
};

class Square : public Shape {
    int m_sides{0};
    int m_sideLength{0};
public: 
    Square() = delete; // suppress default constructor
    Square(int sides, int sideLength): m_sides(sides), m_sideLength(sideLength) {}
    ~Square() {}
    void calculatePerimeter() {
        int perimeter = m_sideLength * m_sides;
        cout << "Square perimeter length: " << perimeter << endl;
    }
};

class Triangle : public Shape {
    int m_sides{0};
    int m_sideLength{0};
public: 
    Triangle() = delete; // suppress default constructor
    Triangle(int sides, int sideLength): m_sides(sides), m_sideLength(sideLength) {}
    ~Triangle() {}
    void calculatePerimeter() {
        int perimeter = m_sideLength * m_sides;
        cout << "Triangle perimeter length: " << perimeter << endl;
    }
};

int main() {
    vector<Shape*> vec;

    vec.push_back(new Square(4, 7));
    vec.push_back(new Triangle(3, 13));

    for (auto x: vec) {
        x->calculatePerimeter();
    }

    // clean up
    purge(vec);

    system("pause");
    return 0;
}

The template way: 模板方式:

template <std::size_t SideCount, typename T>
class EquilateralPolygon
{
public:
    explicit EquilateralPolygon(T sideLength) : sideLength(sideLength) {}
    std::size_t GetSideCount() const { return SideCount; }
    T GetSideLength() const { return sideLength; }

    T calculatePerimeter() const { return SideCount * sideLength; }
private:
    T sideLength;
};

template <std::size_t SideCount, typename T>
void displayPerimeter(const EquilateralPolygon<SideCount, T>& p) {
    std::cout << "perimeter length: " << p.calculatePerimeter() << std::endl;
}

using EquilateralTriangle = EquilateralPolygon<3, std::size_t>;
using Square = EquilateralPolygon<4, std::size_t>;

And usage: 和用法:

int main() {
    Square s(5);
    std::cout << "number of sides a square has: " << s.GetSideCount() << std::endl;

    EquilateralTrianglet(5);
    std::cout << "number of sides a triangle has: " << t.GetSideCount() << std::endl;

    displayPerimeter(s);
    displayPerimeter(t);
}

Live Demo 现场演示

This should answer your question. 这应该可以回答您的问题。 Also, I would recommend passing the values of sides and sideLength as parameters to the function calls to enable generic usage. 另外,我建议将sidessideLength的值作为参数传递给函数调用以启用通用用法。

#include <iostream>

class Shape {
    protected void calculatePerimeter(int sides, int sideLength) {
    int perimeter = sideLength * sides;
    std::cout << "perimeter length: " << perimeter << std::endl;
  }
};

class Square : public Shape {
  int sides = 4;
  int sideLength = 6;
  public void calculatePerimeter()
  {
      Shape::calculatePerimeter(sides, sideLength);
  }
};

class Triangle : public Shape {
  int sides = 3;
  int sideLength = 4;
  public void calculatePerimeter()
  {
      Shape::calculatePerimeter(sides, sideLength);
  }
};

int main() {
  Square s;
  std::cout << "number of sides a square has: " << s.sides << std::endl;

  Triangle t;
  std::cout << "number of sides a triangle has: " << t.sides << std::endl;

  s.calculatePerimeter();
  t.calculatePerimeter();
}

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

相关问题 编写此算法的更有效方法? - More efficient way to write this algorithm? 有没有更有效的方法来编码这部分? - Is there a more efficient way to code this part? 有什么更有效的方法来确保我不会陷入此快速排序功能的无限循环中? (C ++) - What's a more efficient way to make sure I'm not stuck in an infinite loop in this quicksort function? (C++) 在C ++中,有没有更有效的方式来编写多个声明 - In C++, is there a more efficient way to write multiple declarations 我的程序编写每十亿个组合的更有效方法是什么? - A more efficient way for my program to write every billionth combination? 评估中频条件的最有效方法是什么? - What's the most efficient way to evaluate an IF condition? 写入更多文件的最佳方式是什么,而不是内核允许一次打开? - What's the best way to write to more files than the kernel allows open at a time? 更有效的方法来编码c ++中的else语句 - More Efficient way to code if then else statements in c++ 每几毫秒最有效(最快)的方法是什么? - What is the most efficient (fastest) way to write to a file every few milliseconds? 优雅的 C++ 代码:如何使用 while 循环和条件语句编写更高效的代码 - Elegant C++ Code: How to write more efficient code using while loops and conditional statements
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM