#7
by sleep » 7年前
purin52002 さんが書きました:
元の質問のように、継承クラスのunique_ptrを持つクラスのコピーの仕方が依然わからないのですorz
私は読解力が無いためイマイチ理解できてませんが、以下ができれば良いのですか?
・std::unique_ptr でポリモーフィズムを確保する
・std::reverse が扱える
SFINE など重要でないところは省きます。
コード:
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <memory>
#include <algorithm>
using namespace std;
class Base
{
protected:
int i;
public:
Base(int i) : i(i) {}
Base(const Base& obj) { i = obj.i; }
virtual ~Base() { cout << "~Base() : i = " << i << endl; }
virtual string get_status()
{
stringstream ss;
ss << "i = " << i << " : " << typeid(Base).name();
return ss.str();
}
};
class B : public Base
{
public:
using Base::Base;
~B() { cout << "~B(),"; }
string get_status() override
{
stringstream ss;
ss << "i = " << i << " : " << typeid(B).name();
return ss.str();
}
};
class C : public Base
{
public:
using Base::Base;
virtual ~C() { cout << "~C(),"; }
string get_status() override
{
stringstream ss;
ss << "i = " << i << " : " << typeid(C).name();
return ss.str();
}
};
template<typename T>
class MyClass
{
private:
unique_ptr<T> u_ptr;
friend MyClass<Base>;
public:
MyClass(int k)
{
u_ptr = make_unique<T>(k);
}
template<typename M>
MyClass(const M& obj)
{
u_ptr = make_unique<M>(obj);
}
template<typename M>
MyClass(const M&& obj)
{
u_ptr = make_unique<M>(obj);
}
template<typename M>
MyClass(const MyClass<M>& obj)
{
u_ptr = make_unique<M>(*obj.u_ptr);
}
template<typename M>
MyClass(MyClass<M>&& obj)
{
u_ptr = std::forward<MyClass<M>>(obj).u_ptr;
}
void print()
{
cout << u_ptr->get_status() << endl;
}
};
int main()
{
cout << "--------------------" << endl;
{
vector<MyClass<Base>> result;
{
vector<MyClass<Base>> v;
v.reserve(10);
v.emplace_back(1);
v.emplace_back<B>(2);
auto c = C(3);
v.emplace_back(c);
v.emplace_back(MyClass<Base>(4));
v.emplace_back<MyClass<B>>(5);
auto d = MyClass<C>(6);
v.emplace_back(d);
for (auto& obj : v) obj.print();
std::reverse(begin(v), end(v));
result = move(v);
}
cout << "--------------------" << endl;
for (auto& obj : result) obj.print();
}
cout << "--------------------" << endl;
return 0;
}
Windows10(VS 2017)の実行結果
コード:
--------------------
~B(),~Base() : i = 2
i = 1 : class Base
i = 2 : class B
i = 3 : class C
i = 4 : class Base
i = 5 : class B
i = 6 : class C
~C(),~Base() : i = 6
~C(),~Base() : i = 3
--------------------
i = 6 : class C
i = 5 : class B
i = 4 : class Base
i = 3 : class C
i = 2 : class B
i = 1 : class Base
~C(),~Base() : i = 6
~B(),~Base() : i = 5
~Base() : i = 4
~C(),~Base() : i = 3
~B(),~Base() : i = 2
~Base() : i = 1
--------------------
Ubuntu16.10(gcc6.2.0)の実行結果
コード:
--------------------
~B(),~Base() : i = 2
i = 1 : 4Base
i = 2 : 1B
i = 3 : 1C
i = 4 : 4Base
i = 5 : 1B
i = 6 : 1C
~C(),~Base() : i = 6
~C(),~Base() : i = 3
--------------------
i = 6 : 1C
i = 5 : 1B
i = 4 : 4Base
i = 3 : 1C
i = 2 : 1B
i = 1 : 4Base
~C(),~Base() : i = 6
~B(),~Base() : i = 5
~Base() : i = 4
~C(),~Base() : i = 3
~B(),~Base() : i = 2
~Base() : i = 1
--------------------
purin52002 さんが書きました:
コピー(swapの副産物として)がしたい
でも、複数のクラスとリソースを共有したいわけじゃない
safely derived pointer を使用する必要あるんですかね・・・
[quote="purin52002" id=3,19019,144490]
元の質問のように、継承クラスのunique_ptrを持つクラスのコピーの仕方が依然わからないのですorz
[/quote]
私は読解力が無いためイマイチ理解できてませんが、以下ができれば良いのですか?
・std::unique_ptr でポリモーフィズムを確保する
・std::reverse が扱える
SFINE など重要でないところは省きます。
[code]
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <memory>
#include <algorithm>
using namespace std;
class Base
{
protected:
int i;
public:
Base(int i) : i(i) {}
Base(const Base& obj) { i = obj.i; }
virtual ~Base() { cout << "~Base() : i = " << i << endl; }
virtual string get_status()
{
stringstream ss;
ss << "i = " << i << " : " << typeid(Base).name();
return ss.str();
}
};
class B : public Base
{
public:
using Base::Base;
~B() { cout << "~B(),"; }
string get_status() override
{
stringstream ss;
ss << "i = " << i << " : " << typeid(B).name();
return ss.str();
}
};
class C : public Base
{
public:
using Base::Base;
virtual ~C() { cout << "~C(),"; }
string get_status() override
{
stringstream ss;
ss << "i = " << i << " : " << typeid(C).name();
return ss.str();
}
};
template<typename T>
class MyClass
{
private:
unique_ptr<T> u_ptr;
friend MyClass<Base>;
public:
MyClass(int k)
{
u_ptr = make_unique<T>(k);
}
template<typename M>
MyClass(const M& obj)
{
u_ptr = make_unique<M>(obj);
}
template<typename M>
MyClass(const M&& obj)
{
u_ptr = make_unique<M>(obj);
}
template<typename M>
MyClass(const MyClass<M>& obj)
{
u_ptr = make_unique<M>(*obj.u_ptr);
}
template<typename M>
MyClass(MyClass<M>&& obj)
{
u_ptr = std::forward<MyClass<M>>(obj).u_ptr;
}
void print()
{
cout << u_ptr->get_status() << endl;
}
};
int main()
{
cout << "--------------------" << endl;
{
vector<MyClass<Base>> result;
{
vector<MyClass<Base>> v;
v.reserve(10);
v.emplace_back(1);
v.emplace_back<B>(2);
auto c = C(3);
v.emplace_back(c);
v.emplace_back(MyClass<Base>(4));
v.emplace_back<MyClass<B>>(5);
auto d = MyClass<C>(6);
v.emplace_back(d);
for (auto& obj : v) obj.print();
std::reverse(begin(v), end(v));
result = move(v);
}
cout << "--------------------" << endl;
for (auto& obj : result) obj.print();
}
cout << "--------------------" << endl;
return 0;
}
[/code]
Windows10(VS 2017)の実行結果
[code]
--------------------
~B(),~Base() : i = 2
i = 1 : class Base
i = 2 : class B
i = 3 : class C
i = 4 : class Base
i = 5 : class B
i = 6 : class C
~C(),~Base() : i = 6
~C(),~Base() : i = 3
--------------------
i = 6 : class C
i = 5 : class B
i = 4 : class Base
i = 3 : class C
i = 2 : class B
i = 1 : class Base
~C(),~Base() : i = 6
~B(),~Base() : i = 5
~Base() : i = 4
~C(),~Base() : i = 3
~B(),~Base() : i = 2
~Base() : i = 1
--------------------
[/code]
Ubuntu16.10(gcc6.2.0)の実行結果
[code]
--------------------
~B(),~Base() : i = 2
i = 1 : 4Base
i = 2 : 1B
i = 3 : 1C
i = 4 : 4Base
i = 5 : 1B
i = 6 : 1C
~C(),~Base() : i = 6
~C(),~Base() : i = 3
--------------------
i = 6 : 1C
i = 5 : 1B
i = 4 : 4Base
i = 3 : 1C
i = 2 : 1B
i = 1 : 4Base
~C(),~Base() : i = 6
~B(),~Base() : i = 5
~Base() : i = 4
~C(),~Base() : i = 3
~B(),~Base() : i = 2
~Base() : i = 1
--------------------
[/code]
[quote="purin52002" id=3,19019,144498]
コピー(swapの副産物として)がしたい
でも、複数のクラスとリソースを共有したいわけじゃない
[/quote]
safely derived pointer を使用する必要あるんですかね・・・