🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C++11

C++11は2011年に容認されたC++のISO標準です。以前のC++03に代わるもので、中枢の言語の変更・修正、標準ライブラリの拡張・改善を加えたものです。

C++

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

Q&A

解決済

2回答

818閲覧

動的メモリ確保なしでポリモーフィズム

tamaring

総合スコア4

C++11

C++11は2011年に容認されたC++のISO標準です。以前のC++03に代わるもので、中枢の言語の変更・修正、標準ライブラリの拡張・改善を加えたものです。

C++

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

0グッド

3クリップ

投稿2021/02/05 20:31

動的メモリ確保なしでポリモーフィズムを実装しようと思い、以下のような実装にしましたが、これは問題ないでしょうか。

C++

1 2class Base 3{ 4public: 5 virtual void f() = 0; 6 virtual ~Base() = default; 7}; 8 9class Derived1 :public Base 10{ 11 void f()override { std::cout << "Derived1" << std::endl; } 12}; 13class Derived2 :public Base 14{ 15 void f()override { std::cout << "Derived2" << std::endl; } 16}; 17 18template<typename ...Types> 19struct get_max_type_impl; 20 21template<typename MaxType> 22struct get_max_type_impl<MaxType> 23{ 24 using type = MaxType; 25 static constexpr size_t size = sizeof(MaxType); 26}; 27 28template<typename MaxType, typename Head, typename ...Tail> 29struct get_max_type_impl<MaxType, Head, Tail...> : get_max_type_impl<std::conditional_t<(sizeof(MaxType) > sizeof(Head)), MaxType, Head>, Tail... > 30{ 31}; 32 33template<typename Head, typename ...Tail> 34struct get_max_type : get_max_type_impl<Head, Tail...> 35{ 36}; 37 38int main() 39{ 40 std::byte heap[get_max_type<Derived1, Derived2>::size]; 41 Base* d = new(heap) Derived1; 42 d->f(); 43 d->~Base(); 44 d = new(heap) Derived2; 45 d->f(); 46 d->~Base(); 47} 48

main内のstd::byte型配列をメモリとしてplacement newで派生したクラスのメモリを配置しています。
これで問題がなければ利用したいのですが、どうでしょうか。

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

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

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

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

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

episteme

2021/02/06 00:17

デストラクタは動かさなくていいんですよね?
tamaring

2021/02/06 00:39

デストラクタもこちらで確認しましたが、ちゃんと動作するようです。 デストラクタを動かすとなると何か問題があるのでしょうか。
episteme

2021/02/06 01:02

placement new されたオブジェクトを delete したらメモリの開放でトラブるんじゃないかと思って。
tamaring

2021/02/06 01:41

deleteはしていません。 スタック領域のメモリのため、スコープを抜けたら勝手に解放されると思っています。
episteme

2021/02/06 05:33 編集

delete しないってことは、デストラクタは動かんですよね? ...あ、明示的にデストラクトするのか。なら無問題か。
guest

回答2

0

(直接的にはyumetodoさん回答を参照ください。)

alignas/alignofsizeofを用いた実装例としては、下記のようなコードになるでしょうか。C++14以降はstd::maxがconstexpr対応していますから、より直接的にアルゴリズムを記述できます。

c++

1template<typename... Ts> 2constexpr size_t max_alignof() 3{ return std::max({alignof(Ts)...}); } 4 5template<typename... Ts> 6constexpr size_t max_sizeof() 7{ return std::max({sizeof(Ts)...}); } 8 9int main() 10{ 11 constexpr size_t max_align = max_alignof<Derived1, Derived2>(); 12 constexpr size_t max_size = max_sizeof<Derived1, Derived2>(); 13 alignas(max_align) std::byte heap[max_size]; 14 // ... 15}

投稿2021/02/07 05:04

編集2021/02/08 05:23
yohhoy

総合スコア6191

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

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

yumetodo

2021/02/07 09:29

あれ、maxってinitializer_listを受け取るからそれだと3引数でコケるような・・・?
yohhoy

2021/02/08 05:25

yumetodoさん指摘通り max(alignof(Ts)...) → max({alignof(Ts)...}) と記述すべきでした。
guest

0

ベストアンサー

基本形として

cpp

1alignas(T) std::byte t_buff[sizeof(T)];

のようであるべきなんですよね。つまりアラインメントが忘れられてますね。std::aligned_storageがdeprecatedになった理由の解説なんかも参考になります。

https://cpprefjp.github.io/reference/type_traits/aligned_storage.html

デストラクタ呼び出しはstd::destroy_atが便利かなと。

投稿2021/02/06 07:44

yumetodo

総合スコア5852

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問