如何解决C ++前向声明和递归包括
我有8个文件FileSystem.cpp
,Node.cpp
,Directory.cpp
和File.cpp
及其标头hpp
文件。
这是内存文件系统的基本模型。
类FileSystem
负责创建根Directory
,该根拥有自己的节点(即文件或目录)。
类Node
是Directory
和File
的父类。我需要在两个文件中都包含Node
才能继承,但是在Node类实现中,我需要访问File
和Directory
来执行一些操作。如果我尝试使人屈服,那么我将得到类成员的不确定引用。我读了一些有关此的文章,但无法解决标题问题。解决c ++中此类问题的正确方法是什么?我如何/应该使用标题解决此类问题?
请注意,我的背景不同,所以我认为在c ++上缺少有关标头和递归声明的内容。
这是这些文件的来源。
FileSystem.cpp
#include <string>
#include <vector>
#include <iostream>
using namespace std;
#include "Node.hpp"
#include "Directory.hpp"
class FileSystem
{
private:
// methods
// attributes
string name;
Directory *root;
friend class Directory;
public:
int get_fresh_uid()
{
return 10;
}
FileSystem(string in_name)
{
name = in_name;
root = new Directory(this,get_fresh_uid(),"root",nullptr);
}
~FileSystem() {
}
// accessors
string get_name()
{
return name;
}
Directory *get_root()
{
return root;
}
friend ostream &operator<<(ostream &output,FileSystem &fs)
{
return output;
}
};
Node.cpp
#include <string>
#include "Directory.cpp"
#include "File.cpp"
class FileSystem;
using namespace std;
class Node
{
protected:
FileSystem *fs;
int uid;
string name;
Directory *parent;
Node(FileSystem *fs_in,int uid_in,string name_in,Directory *parent_in)
{
fs = fs_in;
name = name_in,uid = uid_in;
parent = parent_in;
}
virtual void print_to(ostream os,int num) = 0;
public:
~Node() {
}
// accessors
string get_name()
{
return name;
}
// methods
virtual bool is_directory() = 0;
virtual Directory *to_directory() = 0;
virtual File *to_file() = 0;
virtual int size() = 0;
};
File.cpp
#include "Node.hpp"
#include "Directory.hpp"
#include "FileSystem.hpp"
class File : public Node
{
private:
string content;
~File() {
}
public:
File(FileSystem *fs_in,Directory *parent_in);
// accessors
void set_content(const string &value)
{
content = value;
}
// mutators
string get_content()
{
return content;
}
// methods
int size()
{
return content.size();
}
bool is_directory()
{
return false;
}
Directory *to_directory()
{
return nullptr;
}
File *to_file()
{
return this;
}
void print_to(ostream os,int num)
{
// os << "+ file: " << name << ",uid: " << uid << ",size: " << size << "," << "content: " << content;
}
};
Directory.cpp
#include "File.hpp"
#include "FileSystem.hpp"
#include "Node.hpp"
class Directory : public Node
{
private:
Directory(FileSystem *fs_in,Directory *parent_in);
~Directory();
// attributes
vector<Node *> children;
// methods
bool child_exists(string name)
{
for (int i = 0; i < children.size(); i++)
{
return children[i]->get_name() == name;
}
}
friend class FileSystem;
public:
// accessors
string get_name() {
return name;
}
//methods
int size()
{
int sum;
for (int i = 0; i < children.size(); i++)
{
Node *child = children[i];
sum += child->size();
}
return sum;
}
bool is_directory()
{
return true;
}
Directory *to_directory()
{
return this;
}
File *to_file()
{
return nullptr;
}
File *add_file(string filename)
{
// check whether same name child node exists
if (child_exists(filename))
return nullptr;
// create file
File *new_file = new File(fs,fs->get_fresh_uid(),filename,this);
// add file to the children vector
children.push_back(new_file);
return new_file;
}
Directory *add_directory(string dirname)
{
// check whether same name child node exists
if (child_exists(dirname))
return nullptr;
// create file
Directory *new_dir = new Directory(fs,dirname,this);
// add dir to the children vector
children.push_back(new_dir);
return new_dir;
}
bool remove_node(string name)
{
for (int i = 0; i < children.size(); i++)
{
if (children[i]->get_name() == name)
{
children.erase(children.begin() + i);
return true;
}
}
return false;
}
Node *find_node(string name)
{
for (int i = 0; i < children.size(); i++)
{
if (children[i]->get_name() == name)
return children[i];
}
return nullptr;
}
void print_to(ostream os,int num)
{
// os << "+ directory: " << name << ",size: " << size;
}
friend ostream &operator<<(ostream &output,Directory &dir)
{
return output;
}
};
Directory::~Directory()
{
for (int i = 0; i < children.size(); i++)
{
delete children[i];
}
}
解决方法
#include "Directory.cpp" #include "File.cpp"
我建议不要将源文件用作标题。按照常规方式编译源文件,但是如果其中一个包含的文件被编译并与“ Node.cpp”文件链接,则由于违反“一个定义规则”,您的程序格式错误。
如果我试图退位,我将得到类成员的不确定引用。
前向声明绝对不能引起“类成员的未定义引用”。您可能误会了一些东西。
在c ++中解决此类问题的正确方法是什么。
简单来说,您需要对定义进行排序,其中依赖的定义要先于依赖的定义排序。当且仅当这种排序不存在时,依存关系图中才会存在一个循环,并且无法通过重新定义定义来解决问题。在这种情况下,必须更改设计。
Node类是Directory和File的父类。我需要将Node包含在要继承的两个文件中,但是在Node类的实现内部,我需要访问文件和目录
这听起来像是糟糕的设计。可能可以实现,但这并不意味着设计一定很好。
也就是说,以下顺序有效:
- 定义节点
- 定义目录和文件
- 定义使用目录和文件的功能
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。