将共享指针与自定义相等运算符和std :: list一起使用时似乎存在问题.
我将以下示例代码放在一起以演示该问题.
在尝试编译之前:
我正在使用 gcc version 4.5.2 20110127
使用以下命令行:
g++ -g -O0 -std=gnu++0x test.cpp
如果未启用c ++ 0x功能,则源将无法编译.
#include<list>
#include<boost/shared_ptr.hpp>
using std::list;
using std::shared_ptr;
using std::cout;
using std::endl;
class TestInt
{
public:
TestInt(int x);
bool operator==(const TestInt& other);
private:
int _i;
};
TestInt::TestInt(int x)
{
_i = x;
}
bool
TestInt::operator==(const TestInt& other)
{
if (_i == other._i){
return true;
}
return false;
}
class Foo
{
public:
Foo(TestInt i);
shared_ptr<TestInt> f(TestInt i);
private:
list<shared_ptr<TestInt>> _x;
};
Foo::Foo(TestInt i) …Run Code Online (Sandbox Code Playgroud) 我有一个包含a BYTE*,一个引用计数器的类,CRITICAL_SECTION它保护它们不受并发访问的影响.
我想用一个替换所有这些std::tr1::shared_ptr<BYTE>.在MSDN说:
多个线程可以同时读写不同的shared_ptr对象,即使这些对象是共享所有权的副本也是如此.
一切听起来都没问题,直到我发现CRITICAL_SECTION课堂外的东西用来"锁定"它并以互相排斥的方式改变它的内容.好吧,它打破了封装,我想改变它.
我知道shared_ptr保证内存将被释放,但是当你写入内存时它是否保证互斥?
我没有看到为什么这些没有为它们被模板化的类型的普通旧指针赋值操作符重载的原因.如果使智能指针的接口尽可能接近普通的旧指针,那么为什么它们不像这样对赋值运算符进行重载?
inline std::shared_ptr<type> &operator=( const type * pointer)
{
reset(a);
}
Run Code Online (Sandbox Code Playgroud)
这样你可以像使用普通指针一样使用它们,如下所示:
std::shared_ptr<int> test = new int;
Run Code Online (Sandbox Code Playgroud)
它根本不是一个问题,只是想知道为什么他们遇到了只是让一些运营商超载的麻烦.
还想知道是否有一种方法来重载全局赋值运算符来执行此操作,或者是否有任何原因我不应该这样做.
编辑:在此处为Nawaz添加关于代码格式的回答.我刚刚编写了这个测试程序,看看你说的是对的:
template<class T>
class peh
{
public:
peh() {meh = 3;}
const peh<T> & operator=(const int * peh)
{
}
};
void f( peh<int> teh)
{
}
int main()
{
int * meh = new int;
f(meh);
system("PAUSE");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这个错误在这里说出来也从没有可用的转换peh<int>来int *.那么,为什么它可以接受std::shared_ptr<int>到int *?
我有以下课程设计:
struct compare{
template <typename T>
bool operator()(const T& a, const T&b){ return *a < *b;}
};
class Trans;
typedef set<shared_ptr<Trans>, compare > TransPointerSet;
class Place{
// other data members
TransPointerSet nextTrans;
public:
// constructor and other methods including overloaded < operator
void insertNextTrans(shared_ptr<Trans> t){ nextTrans.insert(t); }
void removeNextTrans() { nextTrans.clear(); }
};
typedef set<shared_ptr<Place>, compare > PlacePointerSet;
class Trans{
//other data members
PlacePointerSet inPlaces;
PlacePointerSet outPlaces;
public:
//constructor and others including overloaded < operator
void insertInPlace(shared_ptr<Place> p){
inPlaces.insert(p);
p->insertNextTrans(shared_ptr<Trans>(this)); …Run Code Online (Sandbox Code Playgroud) 请原谅这个简单的问题,但是我在理解指向集合的指针时遇到了麻烦。
想象一下,我有这个字节向量:
vector<uint8_t> n;
Run Code Online (Sandbox Code Playgroud)
我想将其存储在共享指针中。为什么需要(&)运算符的地址?
shared_ptr<vector<uint8_t>> m(&n);
Run Code Online (Sandbox Code Playgroud)
我认为构造函数会采用n。但是我也认为我对这里发生的事情有深刻的误解:)
移动shared_ptr会将移动的shared_ptr设置为nullptr,为什么允许它在const_iterator中执行此操作?
std::vector<std::shared_ptr<std::string>> sharedPtrVector;
sharedPtrVector.push_back(std::shared_ptr<std::string>(new std::string("test")));
for (std::vector<std::shared_ptr<std::string>>::const_iterator it = sharedPtrVector.begin(); it != sharedPtrVector.end(); ++it) {
// Not allowed if const_iterator
//*it = nullptr;
// Not allowed if const_iterator
//*static_cast<std::shared_ptr<std::string> *>(&*it) = nullptr;
// Allowed even if const_iterator
std::shared_ptr<std::string> test(std::move(*it));
}
Run Code Online (Sandbox Code Playgroud)
之后,sharedPtrVector处于未定义状态.
我试图用C++解析输入文件.在文件的开头,给出了要读取的行数.读完每一行后,我必须创建一个包含该行数据的对象.我在一个向量中保存一个指向每个对象的指针vector<shared_ptr<MyClass>>.
我想要做的是,只要知道行数,就为所有对象分配足够的空间.但是,我想如果我将该reserve()函数用于我的向量,将分配足够的空间来保存指针而不是对象.
make_shared()在创建对象时使用它会如何改变?换句话说,我应该如何为指针和指针管理器分配足够的空间?我有一个非常奇怪的行为,我无法理解.
该测试通过:
CipString str = *std::make_shared<CipString>("Bye!").get();
EXPECT_EQ(static_cast<std::string>(str), "Bye!");
Run Code Online (Sandbox Code Playgroud)
但这不是:
CipString *str = std::make_shared<CipString>("Bye!").get();
EXPECT_EQ(static_cast<std::string>(*str), "Bye!");
Run Code Online (Sandbox Code Playgroud)
我收到一个错误:
预期:static_cast(*str)
这是:"p\x15\x97\x1"
等于:"再见!"
CipString的代码:
class CipString{
public:
CipString(const std::string& str) {
length = str.size();
string.reset(new uint8_t[length]);
std::copy(str.begin(), str.end(), string.get());
}
operator std::string() const {
std::string str("", length);
std::copy(string.get(), string.get() + length, str.begin());
return str;
}
uint16_t length; /**< Length of the String (16 bit value) */
std::shared_ptr<uint8_t> string; /**< Pointer to the string data */
};
Run Code Online (Sandbox Code Playgroud) 我按照给定的指示尝试解决大学问题.代码编译但会产生关于内存的警告.以下是代码的关键:
#include <iostream>
#include <vector>
#include <memory>
using std::vector;
using std::shared_ptr;
using std::make_shared;
class ApsClass {
protected :
double goose;
public :
virtual ~ApsClass() {}
virtual shared_ptr<ApsClass> clone() const = 0;
double GetGoose() const { return goose; }
};
class DerivedClass : public ApsClass {
public :
~DerivedClass() {} // Warning here*
DerivedClass(double goose) { DerivedClass::goose = goose; }
shared_ptr<ApsClass> clone() const override;
};
shared_ptr<ApsClass> DerivedClass::clone() const {
return make_shared<DerivedClass>(goose);
}
class Storage {
vector<shared_ptr<ApsClass>> geese;
public :
Storage() {} …Run Code Online (Sandbox Code Playgroud) c++ inheritance memory-management shared-ptr virtual-destructor
假设这个类Foo:
struct Foo {
std::shared_ptr<int> data;
std::shared_ptr<std::vector<Foo>> foos;
};
Run Code Online (Sandbox Code Playgroud)
它有一个指向int的指针
它有一个指向此程序中将存在的所有实例的指针(因此其中一个实例== *this)
让我们创建一个实例Foo并在添加一些实例后查看use_count()其.data成员变量.foos:
int main() {
Foo foo;
foo.data = std::make_shared<int>(5);
foo.foos = std::make_shared<std::vector<Foo>>();
foo.foos->resize(8);
for (auto & f : *foo.foos) {
f.data = foo.data;
f.foos = foo.foos;
}
std::cout << "use count: " << foo.data.use_count() << '\n';
}
Run Code Online (Sandbox Code Playgroud)
输出:
use count: 9
Run Code Online (Sandbox Code Playgroud)
哪个好(1 foo+ 8 .foos).但是,似乎在main()返回时,仍会有9个 8指针指向.data!这可以通过放入foo本地范围并让一个额外的指针.data指向 …
shared-ptr ×10
c++ ×9
c++11 ×3
allocation ×1
collections ×1
const ×1
heap ×1
inheritance ×1
iterator ×1
memory ×1
move ×1
new-operator ×1
pointers ×1
stl ×1
unique-ptr ×1
vector ×1
windows ×1