正确地从c++函数传递指针

Properly passing pointer from function C++

本文关键字:指针 函数 c++ 正确地      更新时间:2023-10-16

s_r->info上崩溃,因为s_r没有指向obj2。函数search_recurs()应该找到指针并返回结果。它应该找到正确的指针,因为结果指向obj2

但是当返回结果时发生了一些事情,因为s_r(其中s_r=search_recurs()返回结果)没有指向与应该从搜索返回的result相同的对象。

输出:

W Funkcji search:
Name: zmiana2d
Parameter_a : 5
Parameter_d : 6
adres rzutowanie: 00AFFC50
adres result: 00AFFC50
main:
adres obj2: 00AFFC50
adres s_r: 00AFFB04           //<======= Why is it not 00AFFC50 ? 

代码:

#include "stdafx.h"
using namespace std;

class Node {
private:
public:
    string name;
    Node *parent;
    vector <Node*> children;

    Node() { name = "noname", parent = NULL; }
    Node(string _name) { name = _name, parent = NULL; }
    Node(Node *_parent) { parent = _parent; }
    Node(string _name, Node *_parent) { name = _name, parent = _parent; }
    Node(Node *_parent, vector <Node*> _children) { parent = _parent, children = _children; }
    Node(string _name, Node *_parent, vector <Node*> _children) { name = _name, parent = _parent, children = _children; }
    virtual ~Node() { cout << "Base Destructor calledn"; }

    void add_parent(Node *wsk) {
        parent = wsk;
    }
    void add_children(Node *child) {
        children.push_back(child);
    }
    void info_node() {
        cout << "Name: " << name << endl;
        cout << "Address: " << this << endl;
        cout << "Parent: " << parent << endl;
    }
};

class A { 
private:
    string name;
    int parameter_a;
protected:
    A() { name = "untitled"; parameter_a = 1; }
    A(string _name) { name = _name, parameter_a = 1; }
    A(string _name, int _parameter_a) : name(_name), parameter_a(_parameter_a) {};
    string info_name() {
        return name;
    }
    int info_parameter_a()
    {
        return parameter_a;
    }
public:
    char info_type() {
        return 'A';
    }
    friend class Leaf;
    friend A* search_recurs_node(Node* root, string name);
    virtual void info() = 0;    
};

class Leaf : public Node { 
private:
public:
    vector<A*> objects;
    Leaf() { name = "noname", parent = NULL; }
    Leaf(string _name) { name = _name, parent = NULL; }
    Leaf(Node *_parent) { parent = _parent; }
    Leaf(string _name, Node *_parent) { name = _name, parent = _parent; }
    Leaf(Node *_parent, vector <Node*> _children) { parent = _parent, children = _children; }
    Leaf(string _name, Node *_parent, vector <Node*> _children) { name = _name, parent = _parent, children = _children; }
    void add_objects_leaf(A* obj) {
        objects.push_back(obj);
    }
};

class X : public A, public Leaf {
private:
    int parameter_x;
public:
    X() : A("dziedziczone_w_X_z_A", 98), parameter_x(99) {};
    X(string _name_x, int _parameter_a, int _parameter_x) : A(_name_x, _parameter_a), parameter_x(_parameter_x) {};

    char info_type() {
        return 'X';
    }

    void info() {
        cout << "Name: " << A::info_name() << endl;
        cout << "Parameter_a : " << A::info_parameter_a() << endl;
        cout << "Parameter_d : " << parameter_x << endl;
    }

};

A* search_recurs_node(Node* root, string name) {

    A* result;
    Leaf* rzutowanie;
    if ((root->children.size()) > 0) {
        for (int i = 0; i < (root->children.size()); ++i) {
            search_recurs_node(root->children[i], name);
        }    
    }
    else if (rzutowanie = dynamic_cast<Leaf*>(root)) {
        for (int i = 0; i < rzutowanie->objects.size();++i) {
            if (rzutowanie->objects[i]->info_name() == name) {
                cout << "W Funkcji search: " << endl;
                rzutowanie->objects[i]->info();
                cout << endl << "adres rzutowanie: " << rzutowanie->objects[i] << endl;
                result = (rzutowanie->objects[i]);
                cout << "adres result: " << result << endl;
                cout << endl;
                return result;
            }
        }
    }

    //return NULL;
};
int main()
{
//
    Node A_node("node_A");
    Leaf X_node("node_X", &A_node);
    A_node.add_children(&X_node);
    X obj1("name d1", 1, 2), obj2("zmiana2d", 5, 6);
    X_node.add_objects_leaf(&obj1);
    X_node.add_objects_leaf(&obj2);

    A* s_r;
    s_r = search_recurs_node(&A_node, "zmiana2d");
    cout << "main: " << endl;
    cout << "adres obj2: " << &obj2 << endl;
    cout << "adres s_r: " << s_r << endl;
    s_r->info();
    cout << endl << "The cause of 90% of programming errors sits in front of the screen" << endl;
    return 0;
}

初步评论

obj2的类型为X,继承自ALeaf

返回一个指向A的指针。但是A子对象是用Leaf嵌入X中的;这就是为什么你可以得到另一个地址。您应该将其转换为X*,以确保具有完全相同的地址,无论您的类的布局如何:

 X* x_r = dynamic_cast<X*>(s_r);   // you can, because there's a virtual fct
 if (x_r) 
    cout << "adres x_r: "<<x_r<<endl; 
 else cout << "couldn't cast"<<endl; 
顺便说一下,考虑为任何具有虚函数的类添加虚析构函数。

问题的根本原因

你的递归搜索函数不起作用:你递归地调用它,但你没有对结果做任何事情。修改如下:

...
if ((root->children.size()) > 0) {
    for (int i = 0; i < (root->children.size()); ++i) {
        auto a= search_recurs_node(root->children[i], name);  // <== keep response returned
        if (a)                                    // <== if value already found
           return a;                              // <== return it
    }    
}
...

在函数结束时返回nullptr是明智的(为什么要将其注释掉?)

<<p> 在线演示/strong>