简体   繁体   English

用C ++很难实现链表

[英]Difficulty implementing a linked list in C++

I am trying to implement a linked-list in C++. 我正在尝试在C ++中实现链接列表。 Currently, I have the following code: 目前,我有以下代码:

using namespace std;

struct CarPart
{
    int partNumber;
    char partName[40];
    double unitPrice;

    CarPart* Next;
};

class ListOfParts
{
private:
    int size;
    CarPart* Head;
public:
    ListOfParts():size(0), Head(NULL)
    {    
    }

    int Count()
    {
        return size;
    }
};

Here the problem is, ideally, I should keep the Stuct CarPart within my Class. 这里的问题是,理想情况下,我应该将Stuct CarPart保留在CarPart内。 But I do not want to. 但我不想。 At the same time, I don't want this to be acccessble anywhere from outside. 同时,我不希望任何地方的人都无法做到这一点。

Can I have a some way, without creating a structure within the Class? 我可以在不创建Class的结构的情况下采取某种方法吗? Instead creating a new Class CarPart which could be accessible from only class ListOfPart ?s 而是创建一个只能ListOfPart类访问的新CarPart类。

Well, as a first suggestion, have you considered using std::list ? 好吧,作为第一个建议,您考虑过使用std :: list吗? It would save you the trouble of implementing your own linked list semantics. 这样可以省去实现自己的链表语义的麻烦。 Unless you're writing a linked list for the learning experience (which can be valuable), I suggest using: 除非您为学习经历编写了一个链表(这可能很有价值),否则建议使用:

struct CarPart
{

    int partNumber;
    std::string partName;
    double unitPrice;
};

std::list<CarPart> ListOfParts;

You'll also notice I'm using std::string for text, which I suggest you use (unless you have a very good reason not to). 您还会注意到我在对文本使用std :: string ,我建议您使用它(除非您有很好的理由不这样做)。

To the question at hand: you could declare the constructor for CarPart private, and then declare ListOfParts as a friend class, that's one way. 对于眼前的问题:您可以将CarPart的构造函数声明为私有,然后将ListOfParts声明为朋友类,这是一种方法。 But consider this: what do you gain by disallowing the construction of a car part external to the list of parts? 但是考虑一下:通过禁止在零件清单外部构造汽车零件,您会得到什么? I can't see that you gain anything. 我看不到你有任何收获。 In fact, by using friends you introduce unnecessary complexity into the structure of your code - as using the dreaded 'friend' keyword usually does. 实际上,通过使用Friends,您会在代码结构中引入不必要的复杂性-就像使用可怕的'friend'关键字通常那样。 Anyway, if you did want to use the friend class method, you would write: 无论如何,如果您确实想使用friend class方法,则可以编写:

class ListOfParts;
struct CarPart
{
    friend class ListOfParts;

    int partNumber;
    char partName[40];
    double unitPrice;
    CarPart* Next;

private:

    CarPart()
    {
        // Do nothing.
    }
};

Which would mean only ListOfparts could call the default constructor for the list CarPart. 这意味着只有ListOfparts可以调用列表CarPart的默认构造函数。 Let me make this very clear: this is an abhorrent solution because it breaks rules of encapsulation. 让我非常清楚地说明这一点:这是一个令人讨厌的解决方案,因为它违反了封装规则。 But, like mutable, friends have a use (and this isn't it). 但是,就像易变的一样,朋友也有用(不是吗)。

What you're asking is contradictory. 您要问的是矛盾的。 Either you want CarPart to be accessible from outside (in which case you declare it as a separate class or as a public member) or you don't want it accessible (in which case you declare it as a private member). 您希望CarPart可以从外部访问(在这种情况下,您将其声明为单独的类或公共成员),或者不希望其访问(在这种情况下,您将其声明为私有成员)。

Consider making your class a little more generic: instead of having it be a linked list of CarPart s, make it a class template that makes a linked list of Node s that each has a T . 考虑使您的类更通用:使它不再是CarPart的链表,而应使其成为一个类模板,该模板使每个Node的链表具有T If you are allowed to, you should be using std::list anyway, but you could write your own if you had to/really wanted to. 如果允许的话,无论如何都应该使用std::list ,但是如果必须/真的想要的话,可以编写自己的代码。

Also, classes and structs are basically the same thing; 而且,类和结构基本上是同一件事。 the only difference is that class members and inheritance are by default private, and struct members and inheritance are by default public. 唯一的区别是,默认情况下,类成员和继承是私有的,而默认情况下,结构成员和继承是公开的。 (The keywords are not always interchangeable, though.) (不过,关键字并不总是可以互换的。)

You can move your CarPart struct to a separate header and include this header only in the ListOfParts implementation part (yes, you need to separate definitions from implementations). 您可以将CarPart结构移动到单独的标头,并且仅将此标头包括在ListOfParts实现部分中(是的,您需要将定义与实现分开)。

And don't forget a forward declaration 而且不要忘记前瞻性声明

struct CarPart

before defining 在定义之前

class ListOfParts

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM