Use a destructor with forwarded classes

时间:2016-02-03 04:16:57

标签: c++ class destructor

I have a problem in one of my project. Two classes are using each other, but I solved that problem. The problem is using the destructors. Here's the error log :

location.cpp: In destructor ‘Location::~Location()’:
location.cpp:13:16: warning: possible problem detected in invocation of delete operator: [-Wdelete-incomplete]
         delete it;
                ^
location.cpp:13:16: warning: invalid use of incomplete type ‘class Link’
In file included from location.cpp:1:0:
location.hpp:10:7: note: forward declaration of ‘class Link’
 class Link;
       ^
location.cpp:13:16: note: neither the destructor nor the class-specific operator delete will be called, even if they are declared when the class is defined
         delete it;
                ^
g++ -c -Wall -std=c++11 -g -c link.cpp
link.cpp: In destructor ‘Link::~Link()’:
link.cpp:8:12: warning: possible problem detected in invocation of delete operator: [-Wdelete-incomplete]
     delete src;
            ^
link.cpp:8:12: warning: invalid use of incomplete type ‘class Location’
In file included from link.cpp:1:0:
link.hpp:4:7: note: forward declaration of ‘class Location’
 class Location;
       ^
link.cpp:8:12: note: neither the destructor nor the class-specific operator delete will be called, even if they are declared when the class is defined
     delete src;
            ^
link.cpp:9:12: warning: possible problem detected in invocation of delete operator: [-Wdelete-incomplete]
     delete dst;
            ^
link.cpp:9:12: warning: invalid use of incomplete type ‘class Location’
In file included from link.cpp:1:0:
link.hpp:4:7: note: forward declaration of ‘class Location’
 class Location;
       ^
link.cpp:9:12: note: neither the destructor nor the class-specific operator delete will be called, even if they are declared when the class is defined
     delete dst;
            ^
link.cpp: In member function ‘double Link::length() const’:
link.cpp:14:15: error: invalid use of incomplete type ‘class Location’
     return src->distanceTo(dst);
               ^
In file included from link.cpp:1:0:
link.hpp:4:7: note: forward declaration of ‘class Location’
 class Location;
       ^
Makefile:28: recipe for target 'link.o' failed
make: *** [link.o] Error 1
make: *** Waiting for unfinished jobs....

It seems that the destructor cant call each others, and something's wrong with the Link::length() function.

Here's the code :

location.hpp

#ifndef LOCATION
#define LOCATION

#include <vector>
#include <string>
#include <iterator>
#include <algorithm>
#include <memory>

class Link;

class Location {
    public:
        Location(std::string _name, double _x, double _y);
        ~Location();

        static int next_id;
        int id{ ++next_id };
        std::string name;
        double x, y;
        std::vector<Link*> links;

        std::string toString() const;
        int compareTo( const Location *l ) const;
        double distanceTo( const Location *l ) const;
};

#endif

location.cpp

#ifndef LOCATION
#define LOCATION

#include <vector>
#include <string>
#include <iterator>
#include <algorithm>
#include <memory>

class Link;

class Location {
    public:
        Location(std::string _name, double _x, double _y);
        ~Location();

        static int next_id;
        int id{ ++next_id };
        std::string name;
        double x, y;
        std::vector<Link*> links;

        std::string toString() const;
        int compareTo( const Location *l ) const;
        double distanceTo( const Location *l ) const;
};

#endif

link.hpp

#ifndef LINK
#define LINK

class Location;

class Link {
    public:
        Link(Location *s, Location *d);
        ~Link();

        Location *src{};
        Location *dst{};

        double length() const;
};

#endif

link.cpp

#include "location.hpp"
#include <cmath>

int Location::next_id{ 1 };

Location::Location(std::string _name, double _x, double _y) :
    name(_name), x(_x), y(_y)
{}

Location::~Location()
{
    for(auto &it : links)
        delete it;

    links.clear();
}

std::string Location::toString() const
{
    return name;
}

int Location::compareTo( const Location *l ) const
{
    return id - l->id;
}

double Location::distanceTo( const Location *l ) const
{
    double dx = x - l->x;
    double dy = y - l->y;
    return sqrt(dx*dx + dy*dy);
}

Thanks!

1 个答案:

答案 0 :(得分:1)

您需要在实现Link的文件中包含~Location的头文件。

最好的线索在警告信息中:

  

警告:无效使用不完整类型'class Link'

你遇到的问题是,可以向前声明一个类以防止循环依赖,但是一旦你实际使用它(即当删除Link时),你的源文件需要知道实际的班级声明。