在属于不同类的函数中创建指向类的指针
Posted
技术标签:
【中文标题】在属于不同类的函数中创建指向类的指针【英文标题】:Creating a pointer to a class in a function belonging to a different class 【发布时间】:2021-12-31 20:14:49 【问题描述】:我正在尝试填充类型为 B 类的指针的向量,稍后我将使用它。 当我尝试读取向量的元素时,我得到的值与我给出的不同。 有人可以在这里帮助我,我犯了什么错误以及如何纠正它? 谢谢
#include <iostream>
#include <vector>
class B
public:
int b;
B (int n)
b = n;
;
std::vector<B*> v;
class A
public:
int a;
void func(int n);
;
void A::func(int n)
B obj_b(n);
B* ptr = &obj_b;
v.push_back(ptr);
int main()
A obj_a;
obj_a.a = 5;
obj_a.func(4);
std::cout<<obj_a.a<<std::endl;
for (auto it:v)
std::cout<<it->b<<std::endl;
我得到的输出是: 5、 32765 而预期的输出是: 5、 4
【问题讨论】:
obj_b
在A::func()
返回后立即被销毁。之后,&obj_b
变成了一个悬空指针。
首先,除非你使用继承和多态,否则你几乎不需要指针。请改用B
objects 的向量。如果您有一些(对我们而言)未知的使用指针的要求,请使用 smart 指针,例如std::unique_ptr
。然后使用std::make_unique
动态创建对象,或者如果它不可用,则使用普通new
。
在这种情况下如何完成我想做的事情?
您指向堆栈上的一个值,该值在读取向量时将不再存在 - 然后读取内存中该堆栈帧曾经所在的内存中的随机垃圾。请使用valgrind
运行它并修复那里报告的所有错误。
放下指针。 Here's a start
【参考方案1】:
根据上面的 cmets,使用值而不是指针:
#include <iostream>
#include <vector>
class B
public:
int b;
B (int n)
b = n;
;
std::vector<B> v;
class A
public:
int a;
void func(int n);
;
void A::func(int n)
v.emplace_back(n);
int main()
A obj_a;
obj_a.a = 5;
obj_a.func(4);
std::cout<<obj_a.a<<std::endl;
for (auto& e:v)
std::cout<<e.b<<std::endl;
【讨论】:
建议:不要v.push_back(B(n));
,只做v.emplace_back(n);
@TedLyngmo 同意,我正在 iPad 上写答案,但不确定哪个 C++ 版本引入了 emplace_back。但由于 OP 使用的是 auto,这将是一个更好的解决方案。【参考方案2】:
您可以使用堆分配并利用std::unique_ptr<T>
。这是修复:
#include <iostream>
#include <vector>
#include <memory>
class B
public:
B ( const int n )
b = n;
int b;
;
std::vector< std::unique_ptr<B> > v; // use a vector of B pointers
// ( std::unique_ptr<B> )
class A
public:
void func( const int n );
int a;
;
void A::func( const int n )
v.push_back( std::make_unique<B>( n ) ); // returns a pointer object of type
// std::unique_ptr<B>
int main ()
A obj_a;
obj_a.a = 5;
obj_a.func( 4 );
std::cout << obj_a.a << std::endl;
for ( const auto& ptrB : v )
std::cout << ptrB->b << std::endl; // use -> operator to have access to
// ptrB's members
return 0;
希望这会有所帮助。
【讨论】:
使用new
会起作用,但它确实会带来一个不同的问题——你必须delete
你new
的所有东西,否则它会被泄露。更喜欢使用智能指针而不是原始指针,让标准库为您处理内存管理,例如:std::vector<std::unique_ptr<B>> v; ... v.push_back(std::make_unique<B>(n));
这就是为什么我不愿意使用'new'的原因,我如何在这里使用智能指针?
按照@Remy Lebeau 的建议,我更新了使用智能指针的答案。
@DS_London 已修复。
感谢好心人的时间和精力。以上是关于在属于不同类的函数中创建指向类的指针的主要内容,如果未能解决你的问题,请参考以下文章