如何通过父类对象用共享指针访问子类

发布于 2025-01-10 23:37:29 字数 3598 浏览 3 评论 0原文

我有一个使用父 Node 类和子 Node 类(称为 Transaction)的链表。链表类(称为Ledger)使用共享指针来访问NodeTransaction 类。

我的目标是将 << 运算符与 Node 的共享指针(称为 endPtr)一起使用(链表使用 tail 而不是 head,从最后到第一个),并遍历每个 Node 实例并访问其 Transaction 类变量父 Node 并将其打印出来。

这是我的 Node 头文件:

#pragma once
#include <memory>
#include <string>
#include <vector>
using namespace std;

class Node {
protected:
    shared_ptr<Node> prev;
    string nodeType;
public:
    Node();
    Node(shared_ptr<Node>);

    shared_ptr<Node> getPrev() const;
    void setPrev(shared_ptr<Node>);
    string getType();
};

我的 Transaction 头文件继承自 Node

#pragma once
#include "Node.h"

class Transaction: public Node {
private:
    string toName;
    string fromName;
    int amount;
public:
    Transaction();
    Transaction(string, string, int);


    string getToName() const;
    string getFromName() const;
    int getAmount() const;

    void setToName(string);
    void setFromName(string);
    void setAmount(int);

    shared_ptr<Transaction> getPrev();
    void setPrev(shared_ptr<Transaction>);
};

这是 Ledger 头文件和 cpp 文件:

class Ledger {
private:
    string toName;
    string fromName;
    int amount;
    vector<pair<string, int>> ledgerVector;
    shared_ptr<Node> endPtr;
    int count = 0;
public:
    Ledger();

    Ledger& operator+=(Transaction);
    Ledger& operator-=(shared_ptr<Transaction>);
    void Add(Transaction);
    friend ostream& operator<<(ostream& os, const Ledger&);
};

cpp:

Ledger& Ledger::operator+=(Transaction newTxn) {
    shared_ptr<Transaction> newTransaction = make_shared<Transaction>(newTxn);
    shared_ptr<Node> newPointer = make_shared<Node>(newTxn);

    if (endPtr != nullptr) {
        newPointer->setPrev(endPtr);
        endPtr = newPointer;
    }
    else
        endPtr = newPointer;
}

ostream& operator<<(ostream& os, const Ledger& ledger) {
    weak_ptr<Node> newNode = ledger.endPtr;
    auto node = newNode.lock();
    while (node != nullptr) {
        if (node->getType() == "TRANSACTION") {
            shared_ptr<Transaction> transNode = make_shared<Transaction>(node.get());
            string fromName = transNode->getFromName();
            cout << fromName << endl;
        }
        node = node->getPrev();
    }
}

最后,main.cpp

Transaction t1 = Transaction("Albert", "Bob", 100);
Transaction t2 = Transaction("James", "Alice", 50);
Ledger myLedger;
myLedger += t1;
myLedger += t2;

cout << myLedger;

正如您在 += 运算符中看到的,这就是我添加新事务节点的方式,方法是将Transaction 转换为智能指针,然后创建一个来自同一TransactionNode智能指针。此时,我已将 Ledger 类的 endPtr 分配给它。

这就是 endPtr 的样子,通过 Node 实例可以看出:

image

endPtr 有两个 Node 实例,如中尝试的那样main(),但我不知道 Transaction 的内容是否也存储在其中,也不知道如何访问它。

我知道没有理由这样做,因为它可能不是最佳的,但是任何关于在使用智能指针时通过父对象实例访问继承的类变量的指导将不胜感激。

I have a linked list using a parent Node class and a child Node class (called Transaction). The linked list class (called Ledger) is using shared pointers to access the Node and Transaction class.

My goal is to use the << operator with a shared pointer of Node, called endPtr (the linked list uses a tail instead of a head, going from last to first), and traverse each Node instance and access the Transaction class variables of that parent Node and print them out.

This is my Node header file:

#pragma once
#include <memory>
#include <string>
#include <vector>
using namespace std;

class Node {
protected:
    shared_ptr<Node> prev;
    string nodeType;
public:
    Node();
    Node(shared_ptr<Node>);

    shared_ptr<Node> getPrev() const;
    void setPrev(shared_ptr<Node>);
    string getType();
};

My Transaction header file that inherits from Node:

#pragma once
#include "Node.h"

class Transaction: public Node {
private:
    string toName;
    string fromName;
    int amount;
public:
    Transaction();
    Transaction(string, string, int);


    string getToName() const;
    string getFromName() const;
    int getAmount() const;

    void setToName(string);
    void setFromName(string);
    void setAmount(int);

    shared_ptr<Transaction> getPrev();
    void setPrev(shared_ptr<Transaction>);
};

And this is the Ledger header and cpp files:

class Ledger {
private:
    string toName;
    string fromName;
    int amount;
    vector<pair<string, int>> ledgerVector;
    shared_ptr<Node> endPtr;
    int count = 0;
public:
    Ledger();

    Ledger& operator+=(Transaction);
    Ledger& operator-=(shared_ptr<Transaction>);
    void Add(Transaction);
    friend ostream& operator<<(ostream& os, const Ledger&);
};

cpp:

Ledger& Ledger::operator+=(Transaction newTxn) {
    shared_ptr<Transaction> newTransaction = make_shared<Transaction>(newTxn);
    shared_ptr<Node> newPointer = make_shared<Node>(newTxn);

    if (endPtr != nullptr) {
        newPointer->setPrev(endPtr);
        endPtr = newPointer;
    }
    else
        endPtr = newPointer;
}

ostream& operator<<(ostream& os, const Ledger& ledger) {
    weak_ptr<Node> newNode = ledger.endPtr;
    auto node = newNode.lock();
    while (node != nullptr) {
        if (node->getType() == "TRANSACTION") {
            shared_ptr<Transaction> transNode = make_shared<Transaction>(node.get());
            string fromName = transNode->getFromName();
            cout << fromName << endl;
        }
        node = node->getPrev();
    }
}

Finally, main.cpp:

Transaction t1 = Transaction("Albert", "Bob", 100);
Transaction t2 = Transaction("James", "Alice", 50);
Ledger myLedger;
myLedger += t1;
myLedger += t2;

cout << myLedger;

As you can see in the += operator, that is how I'm adding new transaction nodes, by converting the Transaction into a smart pointer and then creating a Node smart pointer from the same Transaction. At which point, I've assigned it the endPtr of the Ledger class.

This is what the endPtr looks like, as seen through Node instances:

image

The endPtr has two Node instances, as attempted in the main(), but I have no idea if the content of the Transaction is stored in them as well, nor do I know how to access it.

I understand there is no reason to go about it this way, as it may not be optimal, but any guidance on accessing inherited class variables through a parent object instance while using smart pointers would be greatly appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

听风念你 2025-01-17 23:37:29

您的 Ledger 的 operator+= (大概还有 Add())和 operator<< 实现不正确。试试这个:

class Ledger {
    ...
public:
    ...

    Ledger& operator+=(const Transaction&);
    ...
    void Add(const Transaction&);
    friend ostream& operator<<(ostream& os, const Ledger&);
};

void Ledger::Add(const Transaction &newTxn)
{
    auto newPointer = make_shared<Transaction>(newTxn);
    newPointer->setPrev(endPtr);
    endPtr = newPointer;
}

Ledger& Ledger::operator+=(const Transaction &newTxn) {
    Add(newTxn);
    return *this;
}

ostream& operator<<(ostream& os, const Ledger& ledger) {
    auto node = ledger.endPtr;
    while (node != nullptr) {
        auto transNode = dynamic_pointer_cast<Transaction>(node);
        if (transNode != nullptr) {
            os << transNode->getFromName() << endl;
        }
        node = node->getPrev();
    }
    return os;
}

Your Ledger's operator+= (and presumably Add()) and operator<< are implemented incorrectly. Try this instead:

class Ledger {
    ...
public:
    ...

    Ledger& operator+=(const Transaction&);
    ...
    void Add(const Transaction&);
    friend ostream& operator<<(ostream& os, const Ledger&);
};

void Ledger::Add(const Transaction &newTxn)
{
    auto newPointer = make_shared<Transaction>(newTxn);
    newPointer->setPrev(endPtr);
    endPtr = newPointer;
}

Ledger& Ledger::operator+=(const Transaction &newTxn) {
    Add(newTxn);
    return *this;
}

ostream& operator<<(ostream& os, const Ledger& ledger) {
    auto node = ledger.endPtr;
    while (node != nullptr) {
        auto transNode = dynamic_pointer_cast<Transaction>(node);
        if (transNode != nullptr) {
            os << transNode->getFromName() << endl;
        }
        node = node->getPrev();
    }
    return os;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文