从函数 C++ 正确传递指针
Posted
技术标签:
【中文标题】从函数 C++ 正确传递指针【英文标题】:Properly passing pointer from function C++ 【发布时间】:2016-10-31 14:38:15 【问题描述】:它在s_r->info
上崩溃,因为s_r
没有指向obj2
。函数search_recurs()
应该找到指针并返回结果。它应该找到正确的指针,因为结果指向obj2
。
但是在返回结果时会发生一些事情,因为s_r
(s_r=search_recurs()
返回结果)与结果指向的对象不同,应该从搜索返回。
输出:
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 called\n";
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;
【问题讨论】:
并非search_recurs_node
的所有路径都实际返回值。您的递归调用根本不会返回,如果函数刚刚结束,您也不会返回任何内容。不返回任何内容会导致未定义的行为。
【参考方案1】:
初步说明
obj2
是X
类型,它继承自A
和Leaf
。
您返回一个指向A
的指针。但是A
子对象嵌入在X
和Leaf
中;这就是为什么你可以得到另一个地址。您应该将其转换为X*
,以确保具有完全相同的地址whatever the layout of your class:
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
是明智的(为什么要注释掉它?)
Online demo
【讨论】:
刚刚运行它,这就是正在发生的事情 -search_recurs_node
确实找到了正确的节点并将其返回,但是当它返回到顶层时,它不会将它找到的内容返回给调用者。上面的if (a) return(a);
逻辑修复了它。当我取消注释 //return NULL;
时,我得到了一个 nullptr。没有return NULL;
,行为是未定义的,正如@ProgrammerDude 所说。所以你得到了一个地址,但它可能是函数末尾的一个寄存器中剩下的任何内容。
我不知道该如何感谢克里斯托夫!我完全被困住了,你救了我的命:)以上是关于从函数 C++ 正确传递指针的主要内容,如果未能解决你的问题,请参考以下文章