使用する関数がshared_ptrを受け取るようになっていた場合(下記my_useful_function)、当然呼び出すときにshared_ptrでなければいけないが、そのポインタがshared_ptrで管理されていない場合。
unique_ptrであればrelease関数で管理を放棄できるがshared_ptrにはないらしい。
ちなみに無理やりshared_ptrにしてしまうとそのスマートポインタの破棄と同時にdeleteが走るので決してやってはいけない。
#include <iostream> struct MyObject { int value; ~MyObject() { std::cout << "destructor" << std::endl; } }; // この関数は社長の御子息が開発された大変優れたコードであり、開発者は常にこれを呼び出さなければならない。 // 仮に同様の動作をする異なる関数を自作し使用していた場合、現場の混乱を招いたと判断し、 // 最悪解雇も視野に入れた厳重な処分を下す void my_useful_function(std::shared_ptr<MyObject> ptr) { ptr->value = 5; } // この関数は先々代から脈々と受け継がれし伝統ある関数であり、MyObjectの生成には必ずこの関数を呼び出さなければならない。 // 仮に同様の動作をする異なる関数を自作し使用していた場合、現場の混乱を招いたと判断し、 // 最悪解雇も視野に入れた厳重な処分を下す MyObject* my_great_factory() { return new MyObject; }
// 顧客側の要求仕様に則り、この関数の引数を変更してはならない // 仮に同様の動作をする異なる関数を自作し使用していた場合、現場の混乱を招いたと判断し、 // 最悪解雇も視野に入れた厳重な処分を下す void project_job(MyObject* pobect) { // 仕様変更によりmy_normal_functionでは要求を満たせなくなった // 旧コード my_normal_function(pobject) my_useful_function(pobect); //新コード 型が違って呼び出せない }
int main() { MyObject* pmyo = my_great_factory(); project_job(pmyo); std::cout << pmyo->value; delete pmyo; }
スマートポインタにはdeleterを指定できるので、そこに何もしないラムダ関数を指定する。
// 顧客側の要求仕様に則り、この関数の引数を変更してはならない // 仮に同様の動作をする異なる関数を自作し使用していた場合、現場の混乱を招いたと判断し、 // 最悪解雇も視野に入れた厳重な処分を下す void project_job(MyObject* pobect) { // 仕様変更によりmy_normal_functionでは要求を満たせなくなった // 旧コード my_normal_function(pobject) // shared_ptrにする。deleterを指定し、何もしないことでpbojectの参照先が破棄されないようにする std::shared_ptr<MyObject> spobject(pobect, [](auto) {}); my_useful_function(spobject); //新コード shared_ptr型の引数を与える }