【发布时间】:2019-10-19 04:11:44
【问题描述】:
我在超类是 Number 和 Shape 的类开发人员中遇到困难。
实际上,我贴上了虚拟标签,这很容易导致例如 vtable 的错误,我仔细检查了 stackoverflow 中有关 vtable 的所有帖子以及 void 的错误使用,但我最终无法解决此类问题.
您能帮我考虑一下吗?我花了一个多星期来思考这个问题,这真的让我很反感......
如果我的问题需要更多补充的东西,请不要犹豫发表评论,我很乐意与之互动。
NumberMain 程序包括有 NumberMain 的 Complex、Fraction 和 Number。
ShapeMain 程序包括圆形、Shape、Square 和带有 ShapeMain 的三角形。
Circle.cpp
// This class describes the implementation of a Circle
#include <iostream>
#include "Shape.h"
#include "Circle.h"
using namespace std;
Circle & Circle::setCenterX(float newX) {
centerX = newX;
return (*this);
}
Circle & Circle::setCenterY(float newY) {
centerY = newY;
return (*this);
}
// This function changes the radius of the circle. Use validation to ensure radius >=0.
void Circle::setRadius(float newRadius) {
if(newRadius >= 0) {
radius = newRadius;
}
else {
cout << "Error: radius should be at least 0." << endl;
}
}
// This function returns the X coordinate of the center of the circle.
float Circle::getX() const {
return centerX;
}
// This function returns the Y coordinate of the center of the circle.
float Circle::getY() const {
return centerY;
}
// This function returns the radius of the circle.
float Circle::getRadius() const {
return radius;
}
// This function returns the area of the circle.
float Circle::getArea() const {
return radius * radius * PI;
}
// This function returns the diameter of the circle.
float Circle::getDiameter() const {
return 2 * radius;
}
// This function returns the circumference of the circle.
float Circle::getCircumference() const {
return 2 * PI * radius;
}
圆.h
// Circle.h
// This class describes the data and actions for a Circle
#include<iostream>
const float PI = 3.14159;
class Circle : public Shape {
private:
float centerX, centerY, radius;
public:
Circle & setCenterX(float newX);
Circle & setCenterY(float newY);
void setRadius(float newRadius);
float getX() const;
float getY() const;
float getRadius() const;
float getArea() const;
float getDiameter() const;
float getCircumference() const;
};
形状.cpp
// Shape.cpp
// This file describes the Shape class.
#include <iostream>
#include "Shape.h"
using namespace std;
void Shape::setColor(int newColor) {
color = newColor;
}
void Shape::printColor() const {
switch(color) {
case RED : cout << "Red"; break;
case BLUE : cout << "Blue"; break;
case GREEN : cout << "Green"; break;
default : cout << "Black";
}
}
形状.h
// Shape.h
// This file describes the Shape class.
#include <iostream>
const int RED = 1;
const int BLUE = 2;
const int GREEN = 3;
class Shape {
protected:
int color;
public:
virtual void setColor(int newColor);
void printColor() const;
virtual float getArea() const = 0;
};
ShapeMain.cpp
#include <iostream>
#include <stdexcept>
#include "Shape.h"
#include "Circle.h"
#include "Square.h"
#include "Triangle.h"
using namespace std;
// Create and return a Square
Square * makeSquare() {
Square * square1 = new Square();
float sideLength;
cout << "What is the Side Length?";
cin >> sideLength;
square1->setCenterX(0).setCenterY(0).setSideLength(sideLength);
return square1;
}
// Create and return a Circle
Circle * makeCircle() {
Circle * circle1 = new Circle;
float radius;
cout << "What is the Radius?";
cin >> radius;
circle1->setCenterX(0).setCenterY(0).setRadius(radius);
return circle1;
}
Triangle * makeTriangle() {
Triangle * triangle1 = new Triangle();
float height, width;
cout << "What is the Height?";
cin >> height;
cout << "What is the Width?";
cin >> width;
triangle1->setHeight(height).setWidth(width).setLeft(0).setBottom(0);
return triangle1;
}
// Create and return a Color
int makeColor() {
int color;
cout << RED << ") Red or " << BLUE << ") Blue or " << GREEN << ") Green? ";
cin >> color;
return color;
}
int main() {
Shape * shape1;
int color;
int shapeType;
cout << "1) Square or 2) Circle or 3) Triangle?";
cin >> shapeType;
switch(shapeType) {
case 1 : shape1 = makeSquare(); break;
case 2 : shape1 = makeCircle(); break;
case 3 : shape1 = makeTriangle(); break;
default : throw runtime_error("Invalid Shape Class");
}
color = makeColor();
shape1 -> setColor(color);
// The getAre() function is polymorphic.
cout << "The Area is " << shape1->getArea() << endl;
cout << "The Color is ";
shape1->printColor();
cout << endl;
return 0;
}
Square.cpp
// Square.cpp
#include <iostream>
#include "Shape.h"
#include "Square.h"
using namespace std;
Square & Square::setCenterX(float newX) {
centerX = newX;
return (*this);
}
Square & Square::setCenterY(float newY) {
centerY = newY;
return (*this);
}
void Square::setSideLength(float newSideLength) {
if(newSideLength >= 0) {
sideLength = newSideLength;
}
else {
cout << "Error: Side length should be at least 0." << endl;
}
}
float Square::getCenterX() {
return centerX;
}
float Square::getCenterY() {
return centerY;
}
float Square::getSideLength() {
return sideLength;
}
float Square::getArea() {
return sideLength * sideLength;
}
float Square::getTop() {
return centerY + sideLength / 2;
}
float Square::getBottom() {
return centerY - sideLength / 2;
}
float Square::getLeft() {
return centerX - sideLength / 2;
}
float Square::getRight() {
return centerX + sideLength / 2;
}
方形.h
#include<iostream>
class Square : public Shape {
private:
float centerX, centerY, sideLength;
public:
Square & setCenterX(float newX);
Square & setCenterY(float newY);
void setSideLength(float newSideLength);
float getCenterX();
float getCenterY();
float getSideLength();
float getArea() const;
float getTop();
float getBottom();
float getLeft();
float getRight();
};
三角形.cpp
// Triangle.cpp
#include <iostream>
#include "Shape.h"
#include "Triangle.h"
using namespace std;
Triangle & Triangle::setHeight(float newHeight) {
height = newHeight;
return *this;
}
Triangle & Triangle::setWidth(float newWidth) {
width = newWidth;
return *this;
}
Triangle & Triangle::setBottom(float newBottom) {
bottom = newBottom;
return *this;
}
Triangle & Triangle::setLeft(float newLeft) {
left = newLeft;
return *this;
}
float Triangle::getHeight() const {
return height;
}
float Triangle::getWidth() const {
return width;
}
float Triangle::getBottom() const {
return bottom;
}
float Triangle::getLeft() const {
return left;
}
float Triangle::getArea() const {
return ((height * width)/2);
}
void Triangle::setColor(int newColor) {
if (newColor != RED) cout << "Triangles are always Red." << endl;
color = RED;
}
三角形.h
#include<iostream>
class Triangle : public Shape {
private:
float height, width, bottom, left;
public:
Triangle & setHeight(float newHeight);
Triangle & setWidth(float newWidth);
Triangle & setBottom(float newBottom);
Triangle & setLeft(float newLeft);
float getHeight() const;
float getWidth() const;
float getBottom() const;
float getLeft() const;
float getArea() const;
virtual void setColor(int newColor);
};
复杂的.cpp
// Complex.cpp
// This file describes the Complex class.
#include <iostream>
#include "Complex.h"
Complex::Complex() {
real = 0;
imag = 0;
}
Complex::Complex(float newReal) {
real = newReal;
imag = 0;
}
Complex::Complex(float newReal, float newImag) {
real = newReal;
imag = newImag;
}
void Complex::print() {
cout << real << " + j(" << imag << ")" << endl << endl;
}
void Complex::setRealAndImaginary(float newReal, float newImag) {
real = newReal;
imag = newImag;
}
void Complex::setReal(float newReal) {
real = newReal;
}
void Complex::setImaginary(float newImag) {
imag = newImag
}
float Complex::getReal() {
return real;
}
float Complex::getImaginary() {
return imag;
}
// (a + bi) + (c + di) = (a + c) + (b + d)i
Complex Complex::operator+(Complex complex2) {
Complex newComplex;
float newReal = real + complex2.getReal();
float newImag = imag + complex2.getImaginary();
newComplex.setRealAndImaginary(newReal, newImag);
return newComplex;
}
// (a + bi) - (c + di) = (a - b) + (b - d)i
Complex Complex::operator-(Complex complex2) {
Complex newComplex;
float newReal = real - complex2.getReal();
float newImag = imag - complex2.getImaginary();
newComplex.setRealAndImaginary(newReal, newImag);
return newComplex;
}
// (a + bi) * (c + di) = (ac - bd) + (bc + ad)i
Complex Complex::operator*(Complex complex2) {
Complex newComplex;
float newReal = real*complex2.getReal() - imag*complex2.getImaginary();
float newImag = imag*complex2.getReal() + real*complex2.getImaginary();
newComplex.setRealAndImaginary(newReal, newImag);
return newComplex;
}
// (a + bi) / (c + di) = (ac + bd) / (c^2 + d^2) + (bc - ad) / (c^2 + d^2)i
Complex Complex::operator/(Complex complex2) {
Complex newComplex;
float newReal = (real*complex2.getReal() + imag*complex2.getImaginary()) / (complex2.getReal()*complex2.getReal() + complex2.getImaginary()*complex2.getImaginary());
float newImag = (imag*complex2.getReal() - real*complex2.getImaginary()) / (complex2.getReal()*complex2.getReal() + complex2.getImaginary()*complex2.getImaginary());
newComplex.setRealAndImaginary(newReal, newImag);
return newComplex;
}
bool Complex::operator==(Complex complex2) {
return (real == complex2.getReal() && imag == complex2.getImaginary());
}
ostream & operator<<(ostream & output, Complex & complex1) {
output << complex1.getReal() << " + j(" << complex1.getImaginary() << ")";
return output;
}
复杂.h
// Complex.h
// This file describes the Complex class.
using namespace std;
class Complex : public Number {
private:
float real = 0;
float imag = 0;
public:
Complex();
Complex(float newReal);
Complex(float newReal, float newImag);
void print();
void setRealAndImaginary(float newReal, float newImag);
void setReal(float newReal);
void setImag(float newImag);
float getReal();
float getImaginary();
Complex operator+(Complex complex2);
Complex operator-(Complex complex2);
Complex operator*(Complex complex2);
Complex operator/(Complex complex2);
bool operator==(Complex complex2);
};
ostream & operator<<(ostream & output, Complex & complex1);
分数.cpp
// Fraction.cpp
// This file describes the Fraction class.
#include <iostream>
#include "Fraction.h"
// Constructors for Fraction.
// The default fraction is 0/1.
Fraction::Fraction() {
setNumerAndDenom(0, 1);
}
// If only the numerator is given then the default denominator is 1.
Fraction::Fraction(int newNumer) {
setNumerAndDenom(newNumer, 1);
}
Fraction::Fraction(int newNumer, int newDenom) {
setNumerAndDenom(newNumer, newDenom);
}
//Print function for Fraction.
void Fraction::print() {
cout << numerator << "/" << denominator;
}
// This function assigns the fraction to a new value.
void Fraction::setNumerAndDenom(int newNumer, int newDenom) {
if (newDenom == 0) {
cout << "Error creating a fraction with a zero denominator" << endl;
return;
}
numerator = newNumer;
denominator = newDenom;
simplify();
}
// Return the numerator of the fraction.
int Fraction::getNumerator() {
return numerator;
}
// Return the denominator of the fraction.
int Fraction::getDenominator() {
return denominator;
}
// Simplify the fraction. For example 2/4 becomes 1/2.
void Fraction::simplify() {
int gcd = GreatestCommonDenominator(numerator, denominator);
numerator /= gcd;
denominator /= gcd;
}
// Addition operator for Fraction
Fraction Fraction::operator+(Fraction frac2) {
Fraction newFraction;
int newDenom = denominator * frac2.getDenominator();
int newNumer = numerator * frac2.getDenominator() + frac2.getNumerator() * denominator;
newFraction.setNumerAndDenom(newNumer, newDenom);
return newFraction;
}
// Subtraction operator for Fraction
Fraction Fraction::operator-(Fraction frac2) {
Fraction newFraction;
int newDenom = denominator * frac2.getDenominator();
int newNumer = numerator * frac2.getDenominator() - frac2.getNumerator() * denominator;
newFraction.setNumerAndDenom(newNumer, newDenom);
return newFraction;
}
// Multiplication operator for Fraction
Fraction Fraction::operator*(Fraction frac2) {
Fraction newFraction;
int newDenom = denominator * frac2.getDenominator();
int newNumer = numerator * frac2.getNumerator();
newFraction.setNumerAndDenom(newNumer, newDenom);
return newFraction;
}
// Division operator for Fraction
Fraction Fraction::operator/(Fraction frac2) {
Fraction newFraction;
int newDenom = denominator * frac2.getNumerator();
int newNumer = numerator * frac2.getDenominator();
newFraction.setNumerAndDenom(newNumer, newDenom);
return newFraction;
}
// Equality comparison operator for Fraction
bool Fraction::operator==(Fraction frac2) {
return (numerator * frac2.getDenominator() == denominator * frac2.getNumerator());
}
// Greater Than comparison operator for Fraction
bool Fraction::operator>(Fraction frac2) {
return (numerator * frac2.getDenominator() > denominator * frac2.getNumerator());
}
// Less Than comparison operator for fraction
bool Fraction::operator<(Fraction frac2) {
return (numerator * frac2.getDenominator() < denominator * frac2.getNumerator());
}
// Output operator for Fraction
ostream & operator<<(ostream & output, Fraction & frac) {
output << frac.getNumerator() << "/" << frac.getDenominator();
return output;
}
// This function returns the Greatest Common Denominator (GCD) of num1 and num2
int GreatestCommonDenominator(int num1, int num2) {
if (num1 == 0) return num2;
if (num1 < 0) return GreatestCommonDenominator(-num1, num2);
if (num1 > num2) return GreatestCommonDenominator(num2, num1);
return GreatestCommonDenominator(num2-num1, num1);
}
分数.h
// Fraction.h
// This file describes the Fraction class.
using namespace std;
class Fraction : public Number {
private:
int numerator, denominator;
public:
Fraction(); // Default fraction is 0/1.
Fraction(int newNumer);
Fraction(int newNumer, int newDenom);
void print();
void setNumerAndDenom(int newNumer, int newDenom);
int getNumerator();
int getDenominator();
void simplify();
Fraction operator+(Fraction frac2);
Fraction operator-(Fraction frac2);
Fraction operator*(Fraction frac2);
Fraction operator/(Fraction frac2);
bool operator==(Fraction frac2);
bool operator>(Fraction frac2);
bool operator<(Fraction frac2);
};
ostream & operator<<(ostream & output, Fraction & frac1);
int GreatestCommonDenominator(int num1, int num2);
数字.h
// Number.h
// This file describes the Number class.
class Number {
public:
void print() const;
};
NumberMain.cpp
// NumberMain.cpp
// This is the main file which demonstrates the Number class.
#include <iostream>
#include "Number.h"
#inlcude "Fraction.h"
#include "Complex.h"
using namespace std;
// Create and return a Complex
Complex * makeComplex() {
Complex * complex1 = new Complex;
float real, imag;
cout << "What is the Real Part? ";
cin >> real;
cout << "What is the Imaginary Part? ";
cin >> imag;
complex1->setReal(real).setImaginary(imag);
return complex1;
}
// Create and return a Fraction
Fraction * makeFraction() {
Fraction * frac1 = new Fraction;
int numer, denom;
cout << "What is the Numerator? ";
cin >> numer;
cout << "What is the Denominator? ";
cin >> denom;
frac1->setNumerator(numer).setDenominator(denom).simplify();
return frac1;
}
int main() {
Number * num1;
int numberType;
cout << "1) Complex or 2) Fraction ";
cin >> numberType;
switch(numberType) {
case 1 : num1 = makeComplex(); break;
case 2 : num1 = makeFraction(); break;
default : cout << "Error: Invalid Number Class" << endl; return 1;
}
// The print() function is polymorphic
num1->print();
cout << endl;
return 0;
}
谢谢你。
【问题讨论】:
-
除了我的回答中的其他要点之外,
include的拼写不正确,即#inlcude "Fraction.h"。还要注意这些错误。 -
如果您的解决方案正常工作,请考虑通过Code Review 询问。如果您走这条路,请通读链接页面,以便调整您的问题以符合他们的规则。
-
如果您希望您的问题得到更多关注,您可能需要查看How to Ask。我到了你问题的文本部分的结尾,却没有发现你的问题是什么,只是你有问题。 (更准确地说,您的 SO 问题的存在告诉我您遇到了问题;您的问题文本只是证实了这一点。)您的第一段既不吸引人,也不提供信息。提早放弃阅读并将这个问题留给“其他人”很容易。
标签: c++