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