C++ c+的实现+;在默认构造函数中可见的继承类的计数器

C++ c+的实现+;在默认构造函数中可见的继承类的计数器,c++,inheritance,constructor,C++,Inheritance,Constructor,因此,我尝试了多种方法为我的类创建一个计数器,该计数器在构造函数中传递数字 我希望它输出如下内容: input the amount of base class objects: 2 The A# 1: input SomeVar_one: 3 input SomeVar_two: 2 The A# 2: input SomeVar_one: 2 input SomeVar_two: 3 input the amount of derived class objects: 2 The A# 1:

因此,我尝试了多种方法为我的类创建一个计数器,该计数器在构造函数中传递数字

我希望它输出如下内容:

input the amount of base class objects: 2
The A# 1:
input SomeVar_one: 3
input SomeVar_two: 2
The A# 2:
input SomeVar_one: 2
input SomeVar_two: 3
input the amount of derived class objects: 2
The A# 1:
input SomeVar_one: 23
input SomeVar_two: 32
The A# 2:
input SomeVar_one: 12
input SomeVar_two: 42
total # of base objects is: 4
total # of derived objects is: 4
我从哪里得到这个:

input the amount of base class objects: 2
The A# 1:
input SomeVar_one: 3
input SomeVar_two: 2
The A# 2:
input SomeVar_one: 2
input SomeVar_two: 3
input the amount of derived class objects: 2
The A# 3:
input SomeVar_one: 23
input SomeVar_two: 32
The A# 4:
input SomeVar_one: 12
input SomeVar_two: 42
total # of base objects is: 4
total # of derived objects is: 4
请注意,用户提示输入从构造函数调用的值与从
new
操作符调用的值之间存在差异

ofc有必要给他们单独的名字,这也是我想回答的一个问题。你的任何建议都可以接受

主要目标是在调用
new
操作符时实例化对象,而不进入
for
循环,在该循环中,ofc可以调用
“A/B)#(i)”

下面是我使用过的一段代码:它使用“奇怪的重复模板模式”(顺便说一句,这个名字是个杀手!)

//示例
#包括
模板
班级计数器
{
公众:
计数器(bool do_count=true):已计数(do_count)
{
如果(已计数)获取_count()+;
}
~counter()
{
如果(已计数),则获取_count();
}
静态无符号长GetInstanceCount()
{
返回get_count();
}
私人:
布尔数;
静态无符号long&get_count()
{
静态无符号长计数=0;
返回计数;
}
};
类库:公共计数器
{
受保护的:
int m_SomeVar_one=0,m_SomeVar_two=0;
无符号长ObjectNumber=0;
公众:
基本(bool count=true):计数器(count),对象编号(counter::GetInstanceCount())
{
std::cout amountOfDerivedObjects;
base*DerivedArray=新的base[amountOfDerivedObjects];

CRTP与虚拟多态性的结合不太好——虚拟多态性涉及一个公共基类,而CRTP为每个派生类型生成一个不同的基类

无论如何,你可以用合成法破解它。这是一个带有工厂方法模板的计数器的非模板版本。请注意,要进行准确的引用计数,必须使用3规则:

类计数器
{
公众:
模板
静态计数器创建()
{
静态无符号长计数=0;
返回{&count};
}
计数器(const counter&that):count\u addr(that.count\u addr)
{
(*计数地址)+;
}
计数器和运算符=(常量计数器和该计数器)
{
(*计数地址)——;
count\u addr=that.count\u addr;
(*计数地址)+;
归还*这个;
}
~counter()
{
(*计数地址)——;
}
无符号长GetInstanceCount()
{
返回*计数地址;
}
私人:
无符号长*计数地址;
计数器(无符号长*计数地址):计数地址(计数地址)
{
(*计数地址)+;
}
};
然后,您可以将计数器作为基类的成员嵌入,派生类可以选择通过受保护的构造函数提供自己的计数器。公共构造函数转发工厂方法而不是计数器的位是确保没有活动的临时副本,这可能会在 已分配ObjectNumber

类基
{
公众:
base():base(计数器::创建)
{
}
int get_count()
{
返回ctr.getInstanceCount();
}
私人:
计数器ctr;
受保护的:
基本(计数器(*ctr)():ctr(ctr()),ObjectNumber(此->ctr.GetInstanceCount())
{

CRTP与虚拟多态性的结合不太好——虚拟多态性涉及一个公共基类,而CRTP为每个派生类型生成一个不同的基类

无论如何,你可以用合成法破解它。这是一个带有工厂方法模板的计数器的非模板版本。请注意,要进行准确的引用计数,必须使用3规则:

类计数器
{
公众:
模板
静态计数器创建()
{
静态无符号长计数=0;
返回{&count};
}
计数器(const counter&that):count\u addr(that.count\u addr)
{
(*计数地址)+;
}
计数器和运算符=(常量计数器和该计数器)
{
(*计数地址)——;
count\u addr=that.count\u addr;
(*计数地址)+;
归还*这个;
}
~counter()
{
(*计数地址)——;
}
无符号长GetInstanceCount()
{
返回*计数地址;
}
私人:
无符号长*计数地址;
计数器(无符号长*计数地址):计数地址(计数地址)
{
(*计数地址)+;
}
};
然后,您可以将计数器作为基类的成员嵌入,派生类可以选择通过受保护的构造函数提供自己的计数器。公共构造函数转发工厂方法而不是计数器的位是确保没有活动的临时副本,这可能会在 已分配ObjectNumber

类基
{
公众:
base():base(计数器::创建)
{
}
int get_count()
{
返回ctr.getInstanceCount();
}
私人:
计数器ctr;
受保护的:
基本(计数器(*ctr)():ctr(ctr()),ObjectNumber(此->ctr.GetInstanceCount())
{

std::这里要明确的是,您希望您的
计数器
类为继承它的每个类型保留一个单独的计数器,而不是为所有
计数器
类型保留一个计数?您是否尝试过使用字符串类型名到int计数的静态
映射
?是的,我想要而且我确实不知道字符串类型名的映射((我仍然在自己整理它!每个特定的对象都必须有一个计数器,我仍然认为这更像是一个类和构造函数设计问题,因为它如何为不同的类型输出不同的对象号,同时仍然防止代码重复。但是如果有自放大映射这样的东西,它将给出新的类型名基于我可以创建的新类,那就太棒了!!@pohaha你就是这样做的
//sample
#include<iostream>
template <typename T>
class counter
{
public:
    counter(bool do_count = true) : counted(do_count)
    {
        if (counted) get_count()++;
    }
    ~counter()
    {
        if (counted) get_count()--;
    }
    static unsigned long GetInstancesCount()
    {
        return get_count();
    }

private:
    bool counted;
    static unsigned long& get_count()
    {
        static unsigned long count = 0;
        return count;
    }
};


class base:public counter<base>
{
protected:
    int m_SomeVar_one = 0, m_SomeVar_two = 0;
    unsigned long ObjectNumber = 0;
public: 
    base(bool count=true):counter<base>(count),ObjectNumber(counter<base>::GetInstancesCount())
    {
        std::cout << "The A# " << ObjectNumber <<": " << std::endl;
        std::cout << "input SomeVar_one: ";
        std::cin >> m_SomeVar_one;
        std::cout << "input SomeVar_two: ";
        std::cin >> m_SomeVar_two;
    }
    virtual int get_count()
    {
        return counter<base>::GetInstancesCount();
    }
};

class derived :public base, public counter<derived>
{
protected:
    int m_SomeVar_three = 0;

public:
    derived(bool count = true) :base(false), counter<derived>(count)
    {
        std::cout << "input SomeVar_three: ";
        std::cin >> m_SomeVar_three;
    }
    virtual int get_count() override
    {
        return counter<derived>::GetInstancesCount();
    }
};

int main()
{
    std::cout << "input the amount of base class objects: ";
    int amountOfBaseObjects;
    std::cin >> amountOfBaseObjects;
    base* BaseArray = new base[amountOfBaseObjects];


    std::cout << "input the amount of derived class objects: ";
    int amountOfDerivedObjects;
    std::cin >> amountOfDerivedObjects;
    base* DerivedArray = new base[amountOfDerivedObjects];

    std::cout <<"total # of base objects is: "<< BaseArray->get_count() << std::endl;
    std::cout << "total # of derived objects is: " << DerivedArray->get_count() << std::endl;
}