当然,实例化一个方面是不可能的,因为方面不会封装任何特定的功能,而是将其留给从facet派生的特定类,例如整理等。
即,facet类被设计为基类。
出于这个原因,为了防止facet被直接实例化,它的构造函数受到保护,析构函数是虚拟的(以确保正确销毁派生类对象):
class locale::facet
{
protected:
explicit facet(size_t refs = 0);
virtual ~facet();
facet(const facet&) = delete;
void operator=(const facet&) = delete;
};
但是,现在考虑标准的facet collate,它来自facet:
template<typename C>
class collate : public locale::facet
{
public:
/// ...
protected:
~collate(); /// note: protected destructor
virtual int do_compare(
const C* b, const C* e,
const C* b2, const C* e2) const;
virtual string_type do_transform(
const C* b,
const C* e) const;
virtual long do_hash(const C* b,
const C* e) const;
};
请注意,析构函数也受到保护。因此,您无法实例化整理。如果您尝试这样做,您将收到错误:
collate<char> colc;
错误是:
error: 'std::collate<_CharT>::~collate() [with _CharT = char]' is protected|
然而,整理模板类的受保护成员(do_compare(),do_transform()和do_hash())都包含封装的功能,并且不需要使用受保护的dtor声明标准的facet collate
出于这个原因,要创建一个整理,我们需要首先从collate派生一个类,然后可以实例化它!
template<typename C>
class My_collate : public collate<C>
{
public:
explicit My_collate(size_t r = 0) :
collate<C> {r}
{
}
};
My_collate<char> mcolc;
这成功地创建了一个My_collate(通过派生来整理)。
为了证明My_collate封装了继承的功能,我已经成功测试了它:
void print(const string& s1, const string& s2,
const int& rslt)
{
string srslt {};
switch(rslt)
{
case 0:
srslt = "equal";
break;
case 1:
srslt = "s1 > s2";
break;
case -1:
srslt = "s1 < s2";
break;
}
cout << "comparison of " << s1 << " and " << s2
<< " using the mcolc facet : "
<< srslt << endl;
}
void test(const string& s1, const string& s2)
{
/// since compare() operates on char[]s
const char* s1b = s1.data(); /// start of data
const char* s1e = s1b + s1.size(); /// end of data
const char* s2b = s2.data(); /// start of data
const char* s2e = s2b + s2.size(); /// end of data
int rslt = mcolc.compare(s1b, s1e, s2b, s2e);
/// display results
print(s1, s2, rslt);
}
int main()
{
test("Hello", "Hello");
test("Hello", "hello");
test("hello", "Hello");
}
这是输出:
comparison of Hello and Hello using the mcolc facet : equal
comparison of Hello and hello using the mcolc facet : s1 < s2
comparison of hello and Hello using the mcolc facet : s1 > s2
所以,我的问题是:为什么像collate这样的标准方面有一个受保护的析构函数,以便在它们已经封装完整的所需功能时阻止直接实例化?
感谢。
答案 0 :(得分:0)
我已在another forum上发布此查询。
根据回复,似乎这个动作是C ++标准制定者的故意,以防止新手实例化标准库方面,例如整理。
毕竟,正如Stroustrup所述[&#34; The C ++ Programming Language&#34;,4th Ed,pg 1125],
It is essential for one to have a detailed knowledge of individual facets,
to be able to successfully mix and match facets or add new versions of
the standard facets.