不能用'std::shared_ptr_access''类型的表达式初始化'TreeNode'类型的参数。

问题描述 投票:0回答:1

我试图创建一个链接列表,存储一个指向二叉树的指针,二叉树类是由一个通用的子类派生出来的。TreeNode 我做的班级。

TreeNode 类有它的 AddNode 方法的实现(只是作为一个虚函数,但它应该是可调用的),但是当我试图从 TreeNode 我得到了以下错误。

Cannot initialize object parameter of type 'TreeNode' with an expression of type: 'std::__shared_ptr_access<ArtistPlaysNode>,__gnu_cxx::_S_atomic, false, false>::element_type'(aka 'ArtistPlaysNode')

以下是相关部分的内容 TreeNode 类。

// TreeNode.h
class TreeNode {
protected:
    int key;
    int height;
    shared_ptr<TreeNode> father;
    shared_ptr<TreeNode> left;
    shared_ptr<TreeNode> right;
public:
    explicit TreeNode(int key);

    TreeNode(int key, shared_ptr<TreeNode> father, shared_ptr<TreeNode> left, shared_ptr<TreeNode> right);

    virtual StatusType AddNode(shared_ptr<TreeNode> node);
};

// TreeNode.cpp
StatusType TreeNode::AddNode(shared_ptr<TreeNode> node) {
    return INVALID_INPUT;
}

这里是 ArtistPlaysNode:

// ArtistPlaysNode.h
class ArtistPlaysNode : public TreeNode {
private:
    int artistId;
    shared_ptr<SongPlaysNode> SongPlaysTree;
    shared_ptr<MostPlayedListNode> ptrToListNode;
public:
    ArtistPlaysNode(int artistId);
    ArtistPlaysNode(int artistId, shared_ptr<SongPlaysNode> ptrToSongPlaysTree, shared_ptr<MostPlayedListNode> ptrToListNode);
    int GetArtistId();
};

以下是链接的清单,称为 MostPlayedListNode:

// MostPlayedListNode.h
class MostPlayedListNode {
private:
    int numberOfPlays;
    shared_ptr<ArtistPlaysNode> artistPlaysTree;
    shared_ptr<ArtistPlaysNode> ptrToLowestArtistId;
    shared_ptr<SongPlaysNode> ptrToLowestSongId;
    shared_ptr<MostPlayedListNode> previous;
    shared_ptr<MostPlayedListNode> next;

public:
    // Create the first node in the list (0 plays)
    MostPlayedListNode(int numOfPlays);

    // Create a new node with a new highest number of plays
    MostPlayedListNode(int numOfPlays, shared_ptr<MostPlayedListNode> previous);

    // Create a new node with a number of plays between to values (1<2<3)
    MostPlayedListNode(int numOfPlays, shared_ptr<MostPlayedListNode> previous, shared_ptr<MostPlayedListNode> next);

    bool AddArtist(shared_ptr<ArtistPlaysNode> artistNode);
};

这里是发生错误的函数。

// MostPlayedListNode.cpp
bool MostPlayedListNode::AddArtist(shared_ptr<ArtistPlaysNode> artistNode) {
    if (ptrToLowestArtistId) {
        // There are already artists stored in this linked list
        this->artistPlaysTree->AddNode(artistNode); // -->>> this line throws the error.
        return true
    } else {
        this->artistPlaysTree = artistNode;
        return true;
    }
    return false;
}

我试着覆盖了 AddNode 里面的方法 ArtistPlaysNode但这并不奏效,还让编译器抱怨无法从一个指针投向另一个指针。

试着在网上搜索答案,没有找到任何相关结果。

c++ class pointers data-structures smart-pointers
1个回答
0
投票

好的,所以简而言之,这个错误是由于缺少了 远期声明.

请注意 ArtistPlaysNode 类有一个类型为 MostPlayedListNode 属于 SongPlaysNode 作为它的成员。MostPlayedList 类有一个类型为'ArtistPlaysNode'的shared_ptr,类型为 SongPlaysNode 作为它的成员。

此外,这两个 ArtistPlaysNodeSongPlaysNode 源于 TreeNode 类。

这就产生了一种情况,即这些类有其他类型的成员,几乎是以一种循环的方式。

这通常会导致类型的错误。

expected class name before '{' token. 如同在 这个问题

或者可能会造成类型的错误。

'NAME' was not declared in this scope 如以下所示 请在此输入链接描述

为了解决这个问题,我们需要 要么 确保在使用一个类、函数或头文件之前,所有依赖的东西都被声明。

或者 我们需要为编译器提供前向声明,这些声明将允许编译器在没有完整定义的情况下识别该类。

在我的代码中,修复的方法是在 MostPlayedListNode, SongPlaysNodeArtistPlaysNode.

例如,更新后的 MostPlayedListNode.h 文件。

using std::shared_ptr;
using std::make_shared;

class ArtistPlaysNode; // this is a forward declaration
class SongPlaysNode; // this is a forward declaration

class MostPlayedListNode {
private:
    int numberOfPlays;
    shared_ptr<ArtistPlaysNode> artistPlaysTree;
    shared_ptr<ArtistPlaysNode> ptrToLowestArtistId;
    shared_ptr<SongPlaysNode> ptrToLowestSongId;
    shared_ptr<MostPlayedListNode> previous;
    shared_ptr<MostPlayedListNode> next;

public:

和更新后的 ArtistPlayesNode.h 档。

using std::shared_ptr;
using std::make_shared;

class SongPlaysNode; // this is a forward declaration
class MostPlayedListNode; // this is a forward declaration

class ArtistPlaysNode : public TreeNode {
private:
    int artistId;
    shared_ptr<SongPlaysNode> SongPlaysTree;
    shared_ptr<MostPlayedListNode> ptrToListNode;
public:

最后: 在编写某些数据结构的时候,为了让编译器能够识别所有必要的对象,前向声明是很重要的,如果这些对象还没有被引用它们的对象所定义的话。相互递归但情况可能并不总是如此。

© www.soinside.com 2019 - 2024. All rights reserved.