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

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

新規登録して質問してみよう
ただいま回答率
85.48%
デザイン

プログラミングでのデザインとは、プログラムの構成や、使用の信頼性・持続性・正確性・利便性の目標達成にはどうするのがベストなのか特定の選択を行うことです。

C++

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

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

Q&A

解決済

2回答

4749閲覧

[C++] Pimplイディオム [コードデザイン]

退会済みユーザー

退会済みユーザー

総合スコア0

デザイン

プログラミングでのデザインとは、プログラムの構成や、使用の信頼性・持続性・正確性・利便性の目標達成にはどうするのがベストなのか特定の選択を行うことです。

C++

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

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

0グッド

0クリップ

投稿2015/01/28 09:34

こんばんは,みなさんはAPIやその他配布物を作成されるとき,Pimplイディオムを使用されていますか?
また使用時は,Implに隠ぺいする情報には何を選択していますか?

例)
1.プライベートメンバすべて
2.プライベートメンバ変数のみ
3.プライベートメンバメソッドのみ

別の質問になりますが,まず次のコードを見ていただきたいです.
※ 疑似コードよりなので名前や引数,処理は適当です.

// A.h
class A{
private:
class Impl;
Impl mImpl;

public:
// method
};

// A.cpp
class A::Impl{
public:
char *mData;
int mSize;

Impl()
: mData(nullptr),
mSize(0)
{}
};

A::A( /* args... */ )
: mImpl( new A::Impl() )
{
// process...
mImpl->mSize = input.getDataSize();
mImpl->mData = new char[ mImpl->mSize ];
// process...
}

A::~A()
{
delete mImpl;
mImpl = nullptr;
}

このとき,mImpl->mDataのdeleteはclass Implのデストラクタで行うべきなのか,class Aのデストラクタで行うべきなのかどちらなのでしょう?
いまはclass Implでdelete[] mImplと記述してますが,heapメモリの確保はclass Aで行っているのでなんだか気持ち悪いというのがあります.

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

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

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

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

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

guest

回答2

0

ベストアンサー

Pimplイディオム自体は廃れていないと思います。書籍「C++のためのAPIデザイン」でも紹介されています。

ちなみにPimplイディオムを採用するならば、A::Implクラスのデータメンバ(mData,mSize)管理も、外側のAクラスではなくA::Implクラス自身に行わせた方が良いのではないでしょうか?
公開クラスA自身はデータを持たず、公開API呼び出しをうけて実装クラスA::Implに委譲するだけ、という構造が基本パターンだと思います。(それ以外はダメという訳ではないですが、教科書的にはこのような実装パターンです)

このとき,mImpl->mDataのdeleteはclass Implのデストラクタで行うべきなのか,class Aのデストラクタで行うべきなのかどちらなのでしょう?

上記の設計を前提として、「Implのデストラクタで行うべき」だと思います。AA::Implのように密接に関連したクラスであっても、あるクラス(A::Impl)が確保した動的メモリの解放処理を、他クラス(A)に任せる設計は適切ではありません。

投稿2015/02/14 10:32

編集2015/02/14 11:06
yohhoy

総合スコア6191

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

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

0

APIやその他配布物を作成されるとき,Pimplイディオムを使用されていますか?
Implに隠ぺいする情報には何を選択していますか?

ライブラリを作成する際に、OS依存コードや、他ライブラリのヘッダを隠蔽するために使用していました。

mImpl->mDataのdeleteはclass Implのデストラクタで行うべきなのか,
class Aのデストラクタで行うべきなのかどちらなのでしょう?

カプセル化の観点から、newを実行したクラスが、deleteすると思います。
上記コードであれば、Aのコンストラクタで、 mImpl->mData のnewを行っているため、
Aでdeleteを行うと思います。

ただ、mImpl->mData のnew/deleteは、Implで行うほうが良いとは思います。

投稿2015/02/11 03:05

t4410

総合スコア10

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問