プライマリ実行可能ファイルとは異なるコンパイラ/バージョン/プラットフォームでコンパイルされたDLLをリリースしないことを保証すれば、ABIの問題は回避できます。あなたのインターフェイスデザインに関するいかなる速度で
:
void AddControl(Control& control) {
mControls.emplace_back(&control)
}
Control
が多型である(あるいは、少なくとも、あなたがどのようなコードに基づいているように見えるので、あなたは、ここで問題を持っています提供されています)。つまり、完全なオブジェクトを取得するために参照またはポインタで渡す必要がありますが、
- 生ポインタを維持しなければならないインターフェイスを短時間でも公開したくない場合は、 gをアプリケーションに追加します。
これは私がこの問題を回避設計する方法を次のとおりです。
class Window {
public:
void AddControl(std::unique_ptr<Control> control) {//Note we're passing by value!
mControls.emplace_back(std::move(control));
}
private:
std::vector<std::unique_ptr<Control>> mControls;
};
次に、アプリケーション内:これは必ずしも愚かな何かをしてからユーザーを停止しないことを
class MyFinanceApp : public Application {
public:
MyFinanceApp() : mMainWindow(make_unique<Window>()) {
mMainWindow->AddControl(std::make_unique<Button>("testButton"));
}
private:
std::unique_ptr<Window> mMainWindow;
};
注意、like
std::unique_ptr<Window> window_ptr = std::make_Unique<Window>();
Button * button = new Button("This won't be properly deleted!");
window_ptr->AddControl(std::unique_ptr<Button>{button});
delete button; //Whoops!
...しかし、それらを最初から止めているものは何でもあります。
代替案は、コントロールに関連付けられた「工場」を持つことです。
Control & AddControl(std::unique_ptr<Control> control) {
mControls.emplace_back(std::move(control));
return *mControls.back();
}
struct ControlFactory {
static Button & create_button(Window & window, std::string button_text) {
std::unique_ptr<Button> button_ptr = std::make_unique<Button>(button_text);
Button & ref = *button_ptr;
window.AddControl(std::move(button_ptr));
//ref will NOT be invalidated, because the object will still exist in memory,
//in the same location in memory as before. Only the unique_ptr will have changed.
return ref;
}
};
をそして、あなたは、単にエンドユーザーのプログラマーによってそのコンストラクタへの直接アクセスを許可していないすべてのControl
サブクラスのアクセス修飾子を変更する必要があるだろう:私たちは、最初のAddControl
に変更を行う必要があると思います。このような何かはおそらく十分であろう:
class Button : public Control {
/*...*/
protected:
Button() {/*...*/}
Button(std::string text) {/*...*/}
friend class ControlFactory; //Allows ControlFactory to access, even though access is protected.
};
を次にユーザーが、それはあなたがこれらの参照は、アプリケーション自体よりも長生きしないことを保証する必要があるわけんが、ポインタよりも安全である彼らの最後の参照が格納されます。
これらの「明白な理由」は何ですか?個別のヒープは、スマートポインタまたは生ポインタによって所有されているかどうかにかかわらず、動的に割り当てられたオブジェクトに影響します... – Quentin
@Quentin彼はABI問題について話していると思います。ダイナミックライブラリでは、C++のABIは定義されていないので、CのABIはよく定義されているので、Cのインタフェースを持つ方が簡単です。 – nefas
@nefasが正しいです。 – keelerjr12