编写此代码的更有效方法是什么?
What's a more efficient way to write this code?
我是一个c++新手,我正在尝试学习继承。我写了一个程序,它只是简单地打印出不同形状的周长,即一个正方形和一个三角形。不幸的是,我这样做的方式导致了一些重复的代码。我的意思是:
#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();
}
可以看到,calculatePerimeter
函数在Square和Triangle类中被使用。将其放入Shape类中并调用它,结果输出为0。我怎样才能使这更有效,所以我不需要复制/粘贴它为每一个形状类我做?
当您使用继承时,您在基类中考虑公共行为和状态,并使派生类用其特定的功能扩展此状态和行为。
-
从Shape中删除sides和sidelth成员。相反,在类Shape中提供返回这些值的虚函数,并让派生类覆盖它们。
-
移动方法计算圆周到类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; } };
这就是所谓的模板方法设计模式(不要与c++的模板函数概念混淆,这是一个完全不相关的概念,特定于这种语言)。
您需要Shape
的构造函数,并从派生构造函数传递变量。然后可以将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) {}
};
可以访问直接基类成员,也可以初始化它们。
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)
{
}
这将是我对支持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;
}
代码:
int sides = 3;
int sideLength = 4;
正在用局部作用域视图创建新的变量。在不运行代码的情况下,我想如果你只是去掉两行前面的'int'应该可以解决你的问题。
编辑:把它们放到一个构造函数中。
编辑:Ok,组合代码…
class Triangle : public Shape {
public:
Triangle ()
{
sides = 3;
sideLength = 4;
}
void calculatePerimeter() {
int perimeter = sideLength * sides;
std::cout << "perimeter length: " << perimeter << std::endl;
}
};
取决于你想要理解的是什么,其他答案是更好的解决问题的方法。这很简单,只需将参数放入calalateperimeter()方法中,但这当然不能测试您对作用域中变量的理解,这似乎是您的绊脚石。
模板方式:
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>;
和用法:
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);
}
现场演示
这应该可以回答你的问题。此外,我建议将sides
和sideLength
的值作为参数传递给函数调用,以启用通用用法。
#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();
}
- 在C++中初始化向量映射的最有效方法
- 将此布尔值传递给此函数的最有效方法是什么?
- 比较C++变量的最有效方法
- 在 c++ 中解决段树以外的范围查询的有效方法是什么?
- 存储变量的更有效方法是什么?
- 确保套装新鲜度的有效方法
- 当映射包含字符串向量作为值时,从值中获取键的有效方法
- 映射唯一值和重复值的有效方法.可以访问键或值的位置
- 在C++事务之间存储大量字符数据的有效方法
- 在unordered_multimap中精确迭代一次每个键的有效方法
- 一种将 Dart 中的字节数据转换为 C++ 中的无符号字符*的有效方法?
- 检查两个向量是否并行的最有效方法
- 从浮点数中删除小数部分但保留类型的有效方法
- 传递非泛型函数的最有效方法是什么?
- 按升序打印矢量的所有元素直到它为空而没有重复项的最有效方法是什么?
- 创建字符串数组的有效方法
- 返回一个引用C++中另一个类对象的对象的有效方法
- C++去除前x个元素的有效方法,在不改变向量大小的情况下将第x+1个元素推到第一个
- 将一种数据类型的向量复制到同一数据类型的结构向量中的有效方法是什么
- 从std::map值中获取密钥的有效方法