Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/154.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何正确地实现C+中仅由抽象库知道的对象列表的创建(和分配)+;?_C++ - Fatal编程技术网

C++ 如何正确地实现C+中仅由抽象库知道的对象列表的创建(和分配)+;?

C++ 如何正确地实现C+中仅由抽象库知道的对象列表的创建(和分配)+;?,c++,C++,。(-但同时,)或(尽管) 我仔细阅读了所有这些,现在我觉得我知道的比以前少了。我一点也不知道如何编写一个代码,在我看来,这个代码应该是微不足道的,同时尊重所有这些精心编写和深思熟虑的答案中提到的最佳实践 下面是我想要实现的。(我不假装它是正确的C++,但我只是想传达这个想法)。 //这东西纯粹是虚拟的! 类BaseStuff{} //具有不应分割的重要行为和数据成员 类SomeStuff:public BaseStuff{} //请不要把我切成片 类OtherStuff:public Base

。(-但同时,)或(尽管)

我仔细阅读了所有这些,现在我觉得我知道的比以前少了。我一点也不知道如何编写一个代码,在我看来,这个代码应该是微不足道的,同时尊重所有这些精心编写和深思熟虑的答案中提到的最佳实践

下面是我想要实现的。(我不假装它是正确的C++,但我只是想传达这个想法)。
//这东西纯粹是虚拟的!
类BaseStuff{}
//具有不应分割的重要行为和数据成员
类SomeStuff:public BaseStuff{}
//请不要把我切成片
类OtherStuff:public BaseStuff{}
BaseStuff CreateStuff()
{
//落下一组规则,根据月亮的相位创建SomeStuff或OtherStuff实例
}
std::vector CreateListOfStuff()
{
//我经常打电话给你
}
公共静态void main()
{
列出AllTheStaff=CreateListOfStuff();
//用东西处理事情
}

如果想要多态性,必须使用指针

BaseStuff* CreateStuff()
{
   ...
}

List<BaseStuff*> allTheStuff = CreateListOfStuff();
BaseStuff*CreateStuff()
{
...
}
列出AllTheStaff=CreateListOfStuff();
实际上,如果可能的话,您应该更喜欢堆栈分配而不是堆分配。但这并不总是可能的

当然,代替原本不安全的原始指针,您可以考虑使用智能指针等,但智能指针仍然是

List<shared_ptr<BaseStuff>> = CreateListOfStuff
List=CreateListOfStuff

您将存储指向实际指向派生类型的基类的多态指针(注意我在这里使用了
std::unique\u ptr
s):

#包括
#包括
#包括
阶级基础
{
公众:
虚空呼喊()=0;
};
类子:公共基
{
公众:
void shout(){std::cout在这种情况下,您经常(通常?)做的一件事是在基类中定义一个成员函数(传统上称为
clone
),以创建对象的副本:

class BaseStuff { 
public:
    virtual BaseStuff *clone() const = 0;
};

class SomeStuff : public BaseStuff {     
    virtual void SomeStuff *clone() const { 
        return new SomeStuff(*this); // needs a correctly functioning copy ctor
    }
};

class OtherStuff : public BaseStuff {
public: 
    virtual OtherStuff *clone() const { 
        return new OtherStuff(*this);
    }
};
这使我们可以通过指向底部的指针复制项目,而无需切片。通过这种方式,如果您希望(例如)您的
listofsuff
存储您放入其中的项目的副本(而不仅仅是指向原始项目的指针,原始项目可能不再存在,留下悬空指针),您可以添加类似以下内容的项目:

class ListOfStuff { 
    class Node {
        // Note: this is extremely incomplete. Almost certainly needs a dtor,
        // and you want to either implement or delete the copy ctor to either
        // do copying correctly, or assure it can't happen at all.
        Node *next;
        BaseStuff *data;
    public:
        Node(BaseStuff *data, Node *next = nullptr) : data(data), next(next) {}
    };

    Node *begin, *end;

public:
    Add(BaseStuff *item) { 
        BaseStuff *new_item = item->clone();
        end->next = new node(new_item);
        end = end->next;
    }    
};
只要稍加修改,我就同意Armen Tsirunyan的基本观点:当处理多态层次结构时,通常必须通过指针或(修改)引用来完成


在许多情况下,您可以使用智能指针而不是指针——但不是在所有情况下都可以,并且为特定情况选择正确的智能指针本身就非常重要。不过,您通常希望在指针周围使用某种包装器——上面的代码避免使用它们,主要是因为我不太了解您要选择什么他纠正了一个。

所有的
新的
删除
有什么区别?@golergka:这可以处理我的智能指针。请参阅编辑。我会更进一步,将
CreateStuff()
的返回类型更改为智能指针。@golergka:你仍然必须使用
新的
(除非你改用
使你共享()
),但智能指针的全部目的是为您自动调用
delete
。您应该尽可能避免直接调用
new
delete
,让框架来为您处理。感谢您的帮助。但我想要实现的仍然不起作用:@golergka您无法创建
std::vector
const std::unique_ptr
。此外,返回值上的
const
是愚蠢的(如果不是完全无用的话)。只需将变量本身设置为
const
。请参见。谢谢!但我不应该将所有内容默认设置为不可变吗?@golergka它不会产生任何效果;任何人都可以将函数的
const
返回值复制到非
const
变量中。这就是为什么您需要将变量本身设置为
const
,然后离开函数没有。@golergka好吧,语言中有很多东西,它有它的“用途”。关于引用,你是对的,但是指针有着与,比如说,
int
,相同的“问题”,因为你只需将一个副本复制到一个非
常量
变量中。要了解更多的背景信息,请跟随重复的字符串
class BaseStuff { 
public:
    virtual BaseStuff *clone() const = 0;
};

class SomeStuff : public BaseStuff {     
    virtual void SomeStuff *clone() const { 
        return new SomeStuff(*this); // needs a correctly functioning copy ctor
    }
};

class OtherStuff : public BaseStuff {
public: 
    virtual OtherStuff *clone() const { 
        return new OtherStuff(*this);
    }
};
class ListOfStuff { 
    class Node {
        // Note: this is extremely incomplete. Almost certainly needs a dtor,
        // and you want to either implement or delete the copy ctor to either
        // do copying correctly, or assure it can't happen at all.
        Node *next;
        BaseStuff *data;
    public:
        Node(BaseStuff *data, Node *next = nullptr) : data(data), next(next) {}
    };

    Node *begin, *end;

public:
    Add(BaseStuff *item) { 
        BaseStuff *new_item = item->clone();
        end->next = new node(new_item);
        end = end->next;
    }    
};