【发布时间】:2022-01-22 20:08:37
【问题描述】:
我有以下情况:一个类 NoEntry 包含可以被外部世界检查的数据,但是外部世界无论如何都不允许创建这些对象。这样的类看起来像这样:
#ifndef INCLUDED_NOENTRY_
#define INCLUDED_NOENTRY_
#include <string>
class NoEntry
{
std::string d_name;
size_t d_area = 0;
size_t d_date = 0;
public:
std::string const &name() const;
size_t area() const;
size_t date() const;
private:
NoEntry(NoEntry const &other) = default;
NoEntry() = default;
NoEntry(std::string const &name, size_t area, size_t date);
};
#endif
使用 NoEntry 对象是某些类的特权,被声明为 NoEntry 的朋友。所以类包含友元声明:
#ifndef INCLUDED_NOENTRY_
#define INCLUDED_NOENTRY_
#include <string>
class NoEntry
{
friend class PrivilegedOne;
friend class PrivilegedTwo;
std::string d_name;
size_t d_area = 0;
size_t d_date = 0;
public:
std::string const &name() const;
size_t area() const;
size_t date() const;
private:
NoEntry(NoEntry const &other) = default;
NoEntry() = default;
NoEntry(std::string const &name, size_t area, size_t date);
};
#endif
我设计了如下PrivilegedOne接口:
#ifndef INCLUDED_PRIVILEGEDONE_
#define INCLUDED_PRIVILEGEDONE_
#include <iosfwd>
#include <vector>
#include "../noentry/noentry.h"
class PrivilegedOne
{
std::vector<NoEntry> d_noEntry;
public:
PrivilegedOne(std::string const &fname);
private:
NoEntry nextEntry(std::istream &in); // empty name: all were read
};
#endif
它的成员nextEntry很简单:它从文件中读取数据,并返回一个NoEntry对象。
//#define XERR
#include "privilegedone.ih"
NoEntry PrivilegedOne::nextEntry(istream &in)
{
NoEntry ret;
in >> ret.d_name >> ret.d_area >> ret.d_date;
if (not in) // no more NoEntries: ensure
ret.d_name.clear(); // that d_name is empty
return ret;
}
PrivilegedOne 的构造函数必须读取所有 NoEntry 对象,并且必须将它们存储在 d_noEntry 中。这是它的原始实现:
//#define XERR
#include "privilegedone.ih"
PrivilegedOne::PrivilegedOne(string const &fname)
{
ifstream in{ fname };
while (true)
{
NoEntry next = nextEntry(in);
if (next.name().empty())
break;
d_noEntry.push_back(next); // Not working
}
}
“不工作”注释是导致所有问题的行。
为什么声明没有发挥作用? 不修改 NoEntry 类中的任何内容,而只关注 PrivilegedOne:必须做什么才能允许此类的对象将 NoEntry 对象存储在其 d_noEntry 向量中?
我认为我应该重新设计 d_noEntry 的定义。然后我只需要修改带有“不工作”注释的行。
但我不确定如何。
【问题讨论】:
-
“不工作”到底是什么意思?你是在编译时还是运行时出错?
-
它不起作用,因为向量不允许创建自己的元素类型的实例。
-
friend class std::vector<NoEntry>;和一条评论请求您的同事原谅这种不合适的设计。 -
“导致所有问题”是什么意思?
-
@YSC 无法保证它会起作用。尝试创建向量元素的函数不一定是
std::vector的成员。该作业可以委托给不同的类或独立功能。它可能与一个标准库实现一起工作并与另一个标准库实现中断。
标签: c++ vector containers private