在属于不同类的函数中创建指向类的指针

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_bA::func() 返回后立即被销毁。之后,&amp;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&lt;T&gt;。这是修复:

#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 会起作用,但它确实会带来一个不同的问题——你必须deletenew 的所有东西,否则它会被泄露。更喜欢使用智能指针而不是原始指针,让标准库为您处理内存管理,例如:std::vector&lt;std::unique_ptr&lt;B&gt;&gt; v; ... v.push_back(std::make_unique&lt;B&gt;(n)); 这就是为什么我不愿意使用'new'的原因,我如何在这里使用智能指针? 按照@Remy Lebeau 的建议,我更新了使用智能指针的答案。 @DS_London 已修复。 感谢好心人的时间和精力。

以上是关于在属于不同类的函数中创建指向类的指针的主要内容,如果未能解决你的问题,请参考以下文章

指向抽象类的指针

如何在codesys v3中创建指向函数的指针

指向不同类函数的函数指针数组

指向不同类的成员函数的指针

C++ 指向具有匹配函数签名的任何类的成员函数的指针

JavaScript中创建对象过程的理解