#c
#c
Вопрос:
Я получил файл заголовка с именем Shape.h, и мне было поручено создать 4 других файла заголовков, каждый из которых представляет формы: квадрат, прямоугольник, круг и эллипс.
Форма файла заголовка наследуется четырьмя другими файлами заголовков, и исходный файл должен выдавать выходные данные соответственно файлам заголовков.
Я написал коды просто отлично, но результат не даст ожидаемого результата, мне нужна помощь здесь.
Я попросил своих инструкторов о помощи, даже если они помогли, это отняло много времени, но оно того стоило.
реальная проблема здесь в том, что я отлаживал, просматривал код и пробовал разные вещи в коде, но я либо получаю тот же нежелательный результат, либо сообщение об ошибке.
Это базовый файл:
#pragma once
#include <string>
struct Color {
uint8_t r, g, b;
Color(uint8_t _r, uint8_t _g, uint8_t _b) : r(_r), g(_g), b(_b) {}
};
class Shape {
public:
Shape(Color color) : m_color(color) {}
virtual std::string toString() const {
return "color=" std::to_string(m_color.r) ','
std::to_string(m_color.g) ',' std::to_string(m_color.b) 'n';
}
virtual float getArea() const = 0;
virtual float getCircumference() const = 0;
virtual ~Shape();
private:
Color m_color;
};
// note: this method was moved here to satisfy the compiler's need for an
// out-of-line virtual function
Shape::~Shape() {}
Это один из 4 наследуемых заголовочных файлов (Square.h):
#include "Shape.h"
#include <string>
class Square :
public Shape
{
public:
Square(Color rgb, float width) :Shape(rgb), w(width) {}
std::string toString() {
return Shape::toString() 'n'
"width=" std::to_string(w) 'n';
}
float getArea() const override{
return w*w;
}
float getCircumference() const override {
return w*4;
}
private:
float w;
};
И это исходный файл для тестирования:
#include <iostream>
#include <vector>
#include "Shape.h"
#include "Square.h"
void printAttributes(Shape amp;shape) {
std::cout << shape.toString();
;
std::cout << "area=" << std::to_string(shape.getArea()) << std::endl;
std::cout << "circumference=" << std::to_string(shape.getCircumference())
<< 'n'
<< std::endl;
}
int main() {
Color red{255, 0, 0 };
Square square(red, 10.0);
printAttributes(square);
return 0;
}
например, вывод squares должен выглядеть следующим образом:
color=255,0,0
width=10.000000
area=120.000000
circumference=44.000000
мой вывод показывает
color=255,0,0
area=120.000000
circumference=44.000000
Комментарии:
1. @NathanOliver: Он вызывает
shape.toString()
то, что должно. Но код ни на йоту не соответствует ожидаемому результату.2. Как я вижу, не существует версии
Shape
конструктора, которая принимает:Square(Color rgb, float width) :Shape(rgb), w(width)
.3. @MooingDuck Хорошие глаза.
4.
const
отсутствует вtoString
производномSquare
классе.5. Последовательно используйте
override
ключевое слово при переопределении функций в производных классах (а затем отбросьте избыточныеvirtual
). Затем компилятор предупредит вас, когда вы неправильно получите сигнатуру функции и не фактически переопределите что-либо.
Ответ №1:
class Square :
public Shape
{
public:
Square(Color rgb, float width) :Shape(rgb), w(width) {}
std::string toString() const {
return Shape::toString() 'n'
"width=" std::to_string(w) 'n';
}
float getArea() const override{
return w*w;
}
float getCircumference() const override {
return w*4;
}
private:
float w;
};
Добавьте ключевое слово const после метода toString, тогда это переопределит вашу базовую функцию toString . foo() и foo() const не совпадают с формой вашего кодового вызова.toString(). В таблице виртуальных функций не будет переопределяться ваш метод Shape::toString.
Ответ №2:
Исправлен мой предыдущий ответ. Поскольку ваш базовый класс имеет const в сигнатуре функции, а производный класс — нет, функция toString производного класса фактически рассматривается как другая функция. Если вы добавляете const в производный класс или удаляете const из суперкласса, функция работает так, как задумано.
Комментарии:
1. полиморфизм также работает со ссылками, которые использует OP
2. Одна забавная особенность C в том, что VTables — это деталь реализации. Это простое и прямое решение проблемы, поэтому они обычно используются, но достаточно хитрый (или сумасшедший) программист мог бы реализовать полиморфизм с чем-то другим. Может быть, даже Lego.