データベースに接続するクラスを書いています。std::shared_ptr<sql::Driver> driver;
スマート ポインターを使用してすべてを実行する方法を学習しようとしているため、グローバル変数があります。しかし、デストラクタsql::Driver
が保護されているため、これまでのすべてのスマートポインタで常に問題が発生します。driver.reset( )
そのため、常に問題が発生するように呼び出します。スマート ポインターを と組み合わせるにはどうすればよいsql::Driver
ですか?
4 に答える
「 MySQL への Connector/C++ 接続」セクションでは、delete driver
明示的に行う必要はないと述べています。これがerror: ‘virtual sql::Driver::~Driver()’ is protected
. したがって、解決策はdriver
、スマートポインターの代わりにダムポインターを使用することです。(のみdriver
!)
ととはConnection
、スマート ポインターに問題はありません。Statement
ResultSet
// a dumb pointer is used here intentionally, no need to delete it
sql::Driver* driver = get_driver_instance();
// shared_ptr also works
unique_ptr<sql::Connection> con( driver->connect("tcp://127.0.0.1:3306", "root", "root") );
Connector/C++ の完全な例 1とConnector/C++ の完全な例 2 driver
は削除されていないことに注意してください。
保護されている場合は、継承することを意図しているか、破棄のために静的な Destroy() 関数 (または同様のもの) を呼び出す必要があります。前者の場合、次のようにします。
class MyDriver : public sql::Driver
{
public:
virtual ~MyDriver() {} // calls sql::Driver::~Driver() implicitly
// ...
};
おそらく、SQL ライブラリのいくつかの具象クラスがこれを満たします。その場合は、それらの使用方法を探してください。
destroy 関数の場合は、カスタムのデリータを使用します。次のようなものを想定します。
namespace sql
{
class Driver
{
public:
static Driver* Create(); // factory
static void Destroy( Driver* );
// ...
protected:
Driver();
virtual ~Driver();
};
}
あなたはこれをするでしょう:
std::shared_ptr<sql::Driver> driver(
sql::Driver::Create(),
sql::Driver::Destroy );
ただし、一般に、デストラクタは public で virtual 、または private で non-virtual のいずれかにする必要があります。
3 番目のオプションは、sql::Driver がシングルトンであることを意味しますが、継承用に設計されていない限り、dtor はそこでプライベートにする必要があります。
あなたがやろうとしていることは、単に間違っています。プレーンなポインターを使用していた場合はdelete
、まったく呼び出していないことに言及しています。これは、デストラクタが であるという事実とともにprotected
、ポインタ値の所有権を持っていないという事実を示唆しています。
あなたは所有権を持っていないので、指し示す値の一意の共有所有権を扱うunique_ptr
and/or とは何の関係もありません。shared_ptr
そのルートに行くことを主張し、必要のないものの同期で参照カウントを維持するためにかなりのオーバーヘッドを追加する場合は、それを行うことができます。unique_ptr
との両方がDeleterパラメータshared_ptr
を取ることができます。あなたの場合、すでに述べたように、それはno-opになります。
struct noop_deleter
{
void operator ()(void const* ptr) const { /*no-op*/ };
};
shared_ptr<sql::driver>{ driver_ptr, noop_deleter{} };
unique_ptr<sql::driver, noop_deleter>{ driver_ptr, noop_deleter{} };