C++ 当对象超出范围/无效时收到通知
我有一个向量类,它可以返回自身的片段。这些切片将引用实际向量,因此切片和原点都将被修改。问题可能是以下代码段:C++ 当对象超出范围/无效时收到通知,c++,reference,C++,Reference,我有一个向量类,它可以返回自身的片段。这些切片将引用实际向量,因此切片和原点都将被修改。问题可能是以下代码段: class VectorBase { // Offers basic methods } class Vector : VectorBase { // An actual vector } class VectorRef : VectorBase { // References parts of another vector // Construct
class VectorBase {
// Offers basic methods
}
class Vector : VectorBase {
// An actual vector
}
class VectorRef : VectorBase {
// References parts of another vector
// Constructor creates a slice of the base vector
VectorRef(VectorBase base, int start, int end);
}
void foo () {
Vector* a = new Vector();
VectorRef b(*a, 1,4);
delete a;
b.length(); // <---- Problem because a isn't valid anymore
}
类向量库{
//提供基本方法
}
类向量:向量基{
//实际矢量
}
类VectorRef:VectorBase{
//引用另一个向量的部分
//构造函数创建基向量的一个切片
VectorRef(矢量基基、整数起始、整数结束);
}
void foo(){
向量*a=新向量();
向量b(*a,1,4);
删除一条;
b、 length();//如前所述,问题出现了,因为引用引用的对象被破坏。这也是为什么您应该只返回局部变量作为副本,而不是指针/引用。如果您确实想知道对象是否超出范围,可以使用嘈杂的析构函数
~Vector() { std::cout << "Noisy Destructor, reports when an object is destroyed."; }
~Vector(){std::cout如前所述,问题出现了,因为引用所引用的对象被破坏。这也是为什么您只应将局部变量作为副本而不是指针/引用返回的原因。如果您确实想知道某个对象是否超出范围,可以使用嘈杂的析构函数
~Vector() { std::cout << "Noisy Destructor, reports when an object is destroyed."; }
~Vector(){std::cout如前所述,问题出现了,因为引用所引用的对象被破坏。这也是为什么您只应将局部变量作为副本而不是指针/引用返回的原因。如果您确实想知道某个对象是否超出范围,可以使用嘈杂的析构函数
~Vector() { std::cout << "Noisy Destructor, reports when an object is destroyed."; }
~Vector(){std::cout如前所述,问题出现了,因为引用所引用的对象被破坏。这也是为什么您只应将局部变量作为副本而不是指针/引用返回的原因。如果您确实想知道某个对象是否超出范围,可以使用嘈杂的析构函数
~Vector() { std::cout << "Noisy Destructor, reports when an object is destroyed."; }
有几种方法可以解决这个问题
如果您可以访问c++11
或boost
一种方法是使用共享指针和弱指针。这将强制您将向量实例化为共享指针,但您不必实现自己的引用方案。这也意味着VectorRef不拥有向量
class VectorRef : VectorBase {
// References parts of another vector
// Constructor creates a slice of the base vector
VectorRef(std::shared_ptr<VectorBase> base, int start, int end) :
m_base(base), m_start(start), m_end(end)
{
}
std::weak_ptr<VectorBase> m_base;
length() override
{
if (auto base = m_base.lock()) { // Has to be copied into a shared_ptr before usage
{
return m_end-m_start;
}
else
{
trow(VectorException("Base has expired"));
}
}
}
void foo () {
std::shared_ptr<Vector> a = std::make_shared<Vector>();
VectorRef b(a, 1,4);
a.reset();
b.length(); // Will throw an exception
}
类VectorRef:VectorBase{
//引用另一个向量的部分
//构造函数创建基向量的一个切片
VectorRef(std::shared_ptr base,int start,int end):
m_基地(基地)、m_起点(起点)、m_终点(终点)
{
}
std::弱ptr m_基;
长度()覆盖
{
如果(auto base=m_base.lock()){//在使用前必须复制到共享的_ptr中
{
返回m_end-m_start;
}
其他的
{
trow(矢量异常(“基已过期”);
}
}
}
void foo(){
std::shared_ptr a=std::make_shared();
向量b(a,1,4);
a、 重置();
b、 length();//将引发异常
}
有几种方法可以解决这个问题
如果您可以访问c++11
或boost
一种方法是使用共享指针和弱指针。这将强制您将向量实例化为共享指针,但您不必实现自己的引用方案。这也意味着VectorRef不拥有向量
class VectorRef : VectorBase {
// References parts of another vector
// Constructor creates a slice of the base vector
VectorRef(std::shared_ptr<VectorBase> base, int start, int end) :
m_base(base), m_start(start), m_end(end)
{
}
std::weak_ptr<VectorBase> m_base;
length() override
{
if (auto base = m_base.lock()) { // Has to be copied into a shared_ptr before usage
{
return m_end-m_start;
}
else
{
trow(VectorException("Base has expired"));
}
}
}
void foo () {
std::shared_ptr<Vector> a = std::make_shared<Vector>();
VectorRef b(a, 1,4);
a.reset();
b.length(); // Will throw an exception
}
类VectorRef:VectorBase{
//引用另一个向量的部分
//构造函数创建基向量的一个切片
VectorRef(std::shared_ptr base,int start,int end):
m_基地(基地)、m_起点(起点)、m_终点(终点)
{
}
std::弱ptr m_基;
长度()覆盖
{
如果(auto base=m_base.lock()){//在使用前必须复制到共享的_ptr中
{
返回m_end-m_start;
}
其他的
{
trow(矢量异常(“基已过期”);
}
}
}
void foo(){
std::shared_ptr a=std::make_shared();
向量b(a,1,4);
a、 重置();
b、 length();//将引发异常
}
有几种方法可以解决这个问题
如果您可以访问c++11
或boost
一种方法是使用共享指针和弱指针。这将强制您将向量实例化为共享指针,但您不必实现自己的引用方案。这也意味着VectorRef不拥有向量
class VectorRef : VectorBase {
// References parts of another vector
// Constructor creates a slice of the base vector
VectorRef(std::shared_ptr<VectorBase> base, int start, int end) :
m_base(base), m_start(start), m_end(end)
{
}
std::weak_ptr<VectorBase> m_base;
length() override
{
if (auto base = m_base.lock()) { // Has to be copied into a shared_ptr before usage
{
return m_end-m_start;
}
else
{
trow(VectorException("Base has expired"));
}
}
}
void foo () {
std::shared_ptr<Vector> a = std::make_shared<Vector>();
VectorRef b(a, 1,4);
a.reset();
b.length(); // Will throw an exception
}
类VectorRef:VectorBase{
//引用另一个向量的部分
//构造函数创建基向量的一个切片
VectorRef(std::shared_ptr base,int start,int end):
m_基地(基地)、m_起点(起点)、m_终点(终点)
{
}
std::弱ptr m_基;
长度()覆盖
{
如果(auto base=m_base.lock()){//在使用前必须复制到共享的_ptr中
{
返回m_end-m_start;
}
其他的
{
trow(矢量异常(“基已过期”);
}
}
}
void foo(){
std::shared_ptr a=std::make_shared();
向量b(a,1,4);
a、 重置();
b、 length();//将引发异常
}
有几种方法可以解决这个问题
如果您可以访问c++11
或boost
一种方法是使用共享指针和弱指针。这将强制您将向量实例化为共享指针,但您不必实现自己的引用方案。这也意味着VectorRef不拥有向量
class VectorRef : VectorBase {
// References parts of another vector
// Constructor creates a slice of the base vector
VectorRef(std::shared_ptr<VectorBase> base, int start, int end) :
m_base(base), m_start(start), m_end(end)
{
}
std::weak_ptr<VectorBase> m_base;
length() override
{
if (auto base = m_base.lock()) { // Has to be copied into a shared_ptr before usage
{
return m_end-m_start;
}
else
{
trow(VectorException("Base has expired"));
}
}
}
void foo () {
std::shared_ptr<Vector> a = std::make_shared<Vector>();
VectorRef b(a, 1,4);
a.reset();
b.length(); // Will throw an exception
}
类VectorRef:VectorBase{
//引用另一个向量的部分
//构造函数创建基向量的一个切片
VectorRef(std::shared_ptr base,int start,int end):
m_基地(基地)、m_起点(起点)、m_终点(终点)
{
}
std::弱ptr m_基;
长度()覆盖
{
如果(auto base=m_base.lock()){//在使用前必须复制到共享的_ptr中
{
返回m_end-m_start;
}
其他的
{
trow(矢量异常(“基已过期”);
}
}
}
void foo(){
std::shared_ptr a=std::make_shared