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

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

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

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

Q&A

解決済

3回答

12281閲覧

抽象コンストラクタ

mightyMask

総合スコア143

C++

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

1グッド

0クリップ

投稿2017/04/03 16:26

編集2017/04/03 17:25

c++で、抽象コンストラクタを定義することは出来ないのですか?
以下のようなコードを書くとエラーになってしまいます。

c++

1class C { 2 virtual C() = 0; 3};

#追記
ベストアンサーを選ぶ直前に回答して頂いたため、誤って質問を打ち切ってしまいました...
抽象コンストラクタが無理だと分かれば、static create() という関数を使えば良いかなと思って解決済みにしてしまいましたが、それも出来ないのですね。
faithandraveさんの言うようなやり方でやってみようと思います。

#さらに追記
コンストラクタ (続き)
で新たに質問をさせていただきました。
よろしければこちらにも回答して頂けると助かります。

faithandbrave👍を押しています

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

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

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

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

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

guest

回答3

0

こんにちは。

仮想関数はインスタンスを生成することで呼び出せるようになります。
コンストラクト時にvtableへのポインタがインスタンス内に設定されます。)

つまり、コンストラクトするまで仮想関数を呼び出せません。
ですので、コンストラクタ自身を仮想化することはできません。
従って、純粋仮想コンストラクタも有り得ないです。

また、コンストラクタはインスタンスを必要としませんので、staticメンバ関数と考えた方が良いと思います。staticメンバ関数は仮想化できません。

投稿2017/04/03 16:54

Chironian

総合スコア23272

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

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

0

C++のコンストラクタは、仮想関数にはできません。そのため、C++用語での純粋仮想関数(pure virtual function, ここで言う抽象コンストラクタ)にはできません。

オブジェクトの構築を仮想にし、派生クラスで構築の動作をカスタマイズ(多態)したい場合は、コンストラクタの代わりとなるヘルパ関数を用意することになります。
たとえば、

  1. 仮想関数としての構築用メンバ関数を用意し、
  2. クラスのオブジェクトを作成する際には、構築用メンバ関数を呼び出すファクトリー関数を呼び出す

というようなものです:

cpp

1#include <iostream> 2#include <memory> 3 4class A { 5public: 6 virtual void initialize() = 0; 7}; 8 9class B : public A { 10public: 11 void initialize() override 12 { 13 // 派生クラスごとの構築処理を行う 14 std::cout << "B" << std::endl; 15 } 16}; 17 18class C : public A { 19public: 20 void initialize() override 21 { 22 std::cout << "C" << std::endl; 23 } 24}; 25 26template <class T> 27std::shared_ptr<A> factory() 28{ 29 A* x = new T(); 30 x->initialize(); 31 return std::shared_ptr<A>(x); 32} 33 34int main() 35{ 36 std::shared_ptr<A> b = factory<B>(); 37 std::shared_ptr<A> c = factory<C>(); 38}

出力:

B C

構築用メンバ関数であるinitialize()を呼び出さずに構築されることを防ぐため、コンストラクタをprivateにして、ファクトリー関数をfriendにすることも検討するとよいでしょう。

このファクトリー関数とは、オブジェクト指向におけるデザインパターンの一種です。

##参照

投稿2017/04/03 16:51

faithandbrave

総合スコア132

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

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

0

ベストアンサー

構文的にはそのようなことはできないのですが・・・

もしC++のあるクラスが「自分自身を初期化するために特に何もすることがなく、派生クラスが初期化を決めていい」なら基底クラスはコンストラクターを単に省略するか「何もしないもの」として定義すれば済みます。そういう場合にコンストラクターをvirtualとしてわざわざ宣言する必然性はないと考えられます。ゆえに「言語仕様でできないように」なっていると思います。

投稿2017/04/03 16:38

KSwordOfHaste

総合スコア18394

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問