質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

7804閲覧

C++ error: cannot declare variable 'A' to be of abstract type 'B' について

amber_snob

総合スコア30

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2019/07/28 08:41

編集2019/07/28 14:20

c++

1#include <iostream> 2#include <string> 3#include "Shape.h" 4#include "Circle.h" 5#include "Rect.h" 6 7int main(){ 8 Shape** shapes = new Shape*[3]; 9 Circle c1(0,0,2); //純粋仮想関数を含むオブジェクトは生成できない 10 Circle c2(1,1,5); 11 Rect r1(5,5,8,4); 12 shapes[0] = &c1; 13 shapes[1] = &c2; 14 shapes[2] = &r1; 15 for(int i=0; i<3; i++){ 16 std::cout << shapes[i]->area() << std::endl; 17 } 18 delete[] shapes; 19}

上のソースコードを実行したところ、

error: cannot declare variable 'c1' to be of abstract type 'Circle'
error: cannot declare variable 'c2' to be of abstract type 'Circle'
error: cannot declare variable 'r1' to be of abstract type 'Rect'

のようなエラーがでました。

調べると、「純粋仮想関数」を持つクラスのオブジェクトは作れないようで、
virtualがついているメソッドを探したのですが見つかりませんでした。

原因が分からないので教えていただきたいです。
(ちなみに、Rect.h, Circle.hにもエラーが出ています。)

また、Shape.h, Circle.h, Rect.hは次のようになります。

c++

1#ifndef SHAPE_H_ 2#define SHAPE_H_ 3 4#include <sstream> 5#include <string> 6 7class Shape{ 8public: 9 virtual ~Shape() = 0; 10 virtual int area() const = 0; 11 //virtual std::String toString() const = 0; 12}; 13 14inline Shape::~Shape() {}; 15 16/* 17inline std::ostream& operator<<(std::ostream& s, const Shape& shape){ 18 return s << shape.toString(); 19} 20*/ 21 22#endif /* SHAPE_H_ */

c++

1#ifndef CIRCLE_H_ 2#define CIRCLE_H_ 3 4#include "Shape.h" 5#include <math.h> 6 7class Circle: public Shape{ 8protected: //継承先で参照するため 9 int x, y, r; 10public: 11 Circle(int xx, int yy, int rr){ 12 x(xx), y(yy), r(rr) {} 13 } 14 ~Circle() {} 15 int area() { return r * r * M_PI; } 16}; 17 18#endif /* CIRCLE_H_ */

c++

1#ifndef RECT_H_ 2#define RECT_H_ 3 4#include "Shape.h" 5 6class Rect: public Shape{ 7protected: //継承先で参照するため 8 int x, y, w, h; 9public: 10 Rect(int xx, int yy, int ww, int hh){ 11 x(xx), y(yy), w(ww), h(hh) {} 12 } 13 ~Rect() {} 14 int area() { return w * h; } 15}; 16 17#endif /* RECT_H_ */

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

こんちにちは。

Circleの基底クラスのShapeに純粋仮想関数 'virtual int area() const' が宣言されています。
しかし、Circleでは、int area() が定義されているだけです。constがないので異なる関数です。

C++は、引数が異なるとオーバーロードとなるので別の関数です。メンバ関数はこっそりと thisパラメータを持ち、関数名の後に記述した const はそのthisに掛かります。
模式的に書くと、int area() constint area(Shape const* this) というグローバル関数っぽく振る舞います。そして、int area()int area(Shape* this)なのでconstがなくシグニチャが異なるわけです。

つまり、'virtual int area() const' がオーバーライドされていないため、純粋仮想関数がCircleに残っており、コンパイル・エラーとなります。

投稿2019/07/28 09:10

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

次のように修正する必要があります。

diff

1-int area() { return r * r * M_PI; } 2+int area() const { return r * r * M_PI; }

int area(void) と int area(void) const が共存しているのが問題です。

C++

1#include <iostream> 2 3class MyClass { 4public: 5 void func(void) { 6 std::cout << "func\n"; 7 } 8 void func(void) const { 9 std::cout << "func const\n"; 10 } 11}; 12 13int main(void) { 14 MyClass obj1; 15 const MyClass obj2; 16 17 obj1.func(); 18 obj2.func(); 19}

実行結果 Wandbox

func func const

投稿2019/07/28 08:51

LouiS0616

総合スコア35658

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

amber_snob

2019/07/28 14:20 編集

ありがとうございます!エラーが解決しました。 実行結果を示してくださったのと最も早い回答でしたのでベストアンサーとさせていただきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問