C++ 无法实例化标准方面

C++ 无法实例化标准方面,c++,C++,当然,实例化方面是不可能的,因为方面并不封装任何特定的功能,而是将其留给从方面派生的特定类,如collate等 也就是说,facet类被设计为基类 因此,为了防止直接实例化方面,其构造函数受到保护,析构函数是虚拟的(以确保正确销毁派生类对象): 但是,现在考虑标准刻面排序,它是从刻面导出的: template<typename C> class collate : public locale::facet { public: /// ... protected: ~co

当然,实例化方面是不可能的,因为方面并不封装任何特定的功能,而是将其留给从方面派生的特定类,如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:public locale::facet
{
公众:
/// ...
受保护的:
~collate();///注意:受保护的析构函数
虚拟整数比较(
常数C*b,常数C*e,
常数C*b2,常数C*e2)常数;
虚拟字符串类型do转换(
常数C*b,
常数C*e)常数;
虚拟长do_散列(常数C*b,
常数C*e)常数;
};
请注意,这里的析构函数也是受保护的。因此,您将无法实例化collate。如果您尝试这样做,您将得到一个错误:

collate<char> colc;
整理colc;
错误是:

error: 'std::collate<_CharT>::~collate() [with _CharT = char]' is protected|
错误:“std::collate::~collate()|
但是,collate模板类的受保护成员(do_compare()、do_transform()和do_hash())都包含封装的功能,并且不需要使用受保护的dtor声明标准方面的collate

出于这个原因,要创建一个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\u collate(大小\u t r=0):
校对{r}
{
}
};
我的校对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");
}
void打印(常量字符串和s1,常量字符串和s2,
常量(整数和rslt)
{
字符串srslt{};
开关(rslt)
{
案例0:
srslt=“相等”;
打破
案例1:
srslt=“s1>s2”;
打破
案例1:
srslt=“s1我已经把这个问题发到网上了

基于回答,该行为似乎是在C++标准设置器的一部分上故意的,以防止初学者对标准库方面进行实例化,例如CORATET.<

毕竟,正如Stroustrup所说的“C++编程语言”,第四ED,PG 1125,< /P>

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.

根据,
facet
包含用于管理其生命周期的引用计数。如果您可以将具有自动存储持续时间的
facet
传递给
std::locale
,例如
std::collate c;std::locale(loc,c);
。不,事实上
collate c
(如果这样的操作是可能的)将创建一个必须由区域设置管理的方面,因为默认的ctor arg是0,是的,但只要您将它传递给
std::locale(loc,&c)
(我在前面的评论中忘记了
&
),则
locale
将增加引用计数器并开始共享
collate
的所有权,这将在locale在其生命周期结束时尝试删除
collate
时引发问题。您不应向locale添加具有自动存储持续时间的方面,这可能就是此析构函数我的观点是,这可以防止您在不知情的情况下做错事,这基本上就是您在cplusplus.com上得到的答案“自动存储持续时间”,我认为您指的是使用ctor arg refs=0(默认值)创建的方面;即,生存期由区域设置管理的刻面。据我所知,要将刻面添加到区域设置,刻面的生存期必须由区域设置管理,而不是手动管理。您为什么说不应该这样做?根据自动存储持续时间,我指的是
collate
,即它是
std::collate
th未使用
new
分配as(基本上是堆栈上的局部变量)。如果您有这样一个
std::collate
对象,您不能将其与
std::locale
一起使用,因为locale将尝试
删除它,这将导致UB,因为
std::collate
未分配
new
。我确实理解这种混淆,因为
方面在某种意义上是“自动”的管理,但我不是指柜台;)
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
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.