简体   繁体   English

如何从类成员函数返回指针,例如 size_t * class :: function(); 并使用类析构函数 ~size_t*class::function();

[英]How do I return a pointer from a class member function e.g. size_t * class :: function(); and use a class destructor ~size_t*class::function();

I am at the point learning classes/destructors in c++ and the need to return a pointer from a class member:我正在学习 C++ 中的类/析构函数,并且需要从类成员返回指针:

size_t * classname :: function();

but it doesn't work.但它不起作用。

My logic is to declare a class variable eg classname * p_p = classfunction(data);我的逻辑是声明一个类变量,例如classname * p_p = classfunction(data); that should access the class member:应该访问类成员:

size_t * classname :: classfunction(data)
{
    //... do something ... 
    new p_p;

    return p_p;
}

So the pointer address in theory gets returned to the main() variable p_p each time the member function of the class gets called.因此,每次调用类的成员函数时,理论上的指针地址都会返回到main()变量p_p Or should but doesn't and the program crashes somehow but not even sure on which point.或者应该但不应该并且程序以某种方式崩溃但甚至不确定在哪一点。

There is no compiler warning or error and the debugger doesn't stops anywhere and I find nothing on returning a pointer from a class member function at all nor that it isn't allowed or something.没有编译器警告或错误,调试器不会在任何地方停止,而且我根本没有发现从类成员函数返回指针的任何内容,也没有发现它是不允许的或什么的。

Also if there IS a syntax to return a pointer from a class member function I would need to have a syntax for delete the " new p_p ".此外,如果有一种语法可以从类成员函数返回指针,我将需要一种语法来删除“ new p_p ”。

So my question is: Should it work and how would I get this running or why is that maybe it is not working or forbidden?所以我的问题是:它应该工作,我将如何运行它,或者为什么它可能不起作用或被禁止? In my logic it should be a proper way but I may be wrong somehow and classes doesn't support this function completely.在我的逻辑中,它应该是一种正确的方式,但我可能以某种方式错了,并且类不完全支持此功能。

EDIT:编辑:

Thanks to your answers and comments I got the pointer returned from the class member.感谢您的回答和评论,我得到了班级成员返回的指针。 (Also changed size_t to int since its just a pointer.) Like you suggested in the comments I added a minimal reproducible example: (也将size_t更改为int因为它只是一个指针。)就像您在评论中建议的那样,我添加了一个最小的可重现示例:

#include <iostream>

using namespace std;
//########## class without ~ destructor ##########
class classname
{
public:
    int *ptr;
    int *classfunction(int);
    void delete_classfunction(int*);
};


void classname::delete_classfunction(int*ptr)
{
    delete[] ptr;
    ptr = nullptr;
}

int *classname :: classfunction(int value)
{
    int* ptr = new int[value]; //no delete?
    ptr[0] = 5;
    return ptr;
}
//########## class with ~destructor ##########
class classname_c
{
public:
    int *ptr;
    int value;

    *classname_c(int );
    void print(int*);
    ~classname_c();

};

void classname_c::print(int* ptr)
{
    cout << ptr[0] << " shows value" << endl;
}

*classname_c::classname_c(int value)
{
    int* ptr = new int[value];
    ptr[0] = value;
} /*Brings warning: control reaches end of non-void function [-Wreturn-type]
   48 | }
      | ^*/


classname_c::~classname_c ()
{
    cout << ptr[0] << endl;
    delete[] ptr;
    ptr = nullptr;
    cout << ptr[0] << endl;
}

int main()
{   //class and deleting it myself calling the function delte
    int value = 3;
    int *ptr;
    classname call;
    ptr = call.classfunction(value); //create new ptr
    cout << ptr[0] << " shows value" << endl;
    call.delete_classfunction(ptr); //free memory
    cout << ptr[0] << " shows value succ. deleted" << endl;

    //class with destructor
    classname_c dest(value);
    dest.print(ptr);
    cout << ptr[0] << " shows value succ. deleted" << endl; //its not!


    return 0;
}

brings the following output:带来以下输出:

5 shows value
0 shows value succ. deleted //How it should be
3 shows value
3 shows value succ. deleted  //but its not, why? What did I do wrong?
Press <RETURN> to close this window...

Now I am not sure if/when the ~destructor is working or how I can test if I created the destructor right, because the ptr value is not deleted.现在我不确定 ~destructor 是否/何时工作,或者我如何测试我是否正确创建了析构函数,因为 ptr 值没有被删除。 Also can I fix the我也可以修复

warning: control reaches end of non-void function [-Wreturn-type]
   48 | }
      | ^

It is perfectly fine to return a pointer from a member function, although returning a pointer to an allocated size_t seem a bit overkill.从成员函数返回一个指针是完全没问题的,尽管返回一个指向分配的size_t的指针似乎有点矫枉过正。

What you want is probably something like this:你想要的可能是这样的:

#include <iostream>

class cls
{
public:
    size_t *ptr_func();
};

size_t *cls::ptr_func()
{
    size_t *p = new size_t(42);

    return p;
}

int main()
{
    cls c;
    size_t *p = c.ptr_func();

    std::cout << (void *)p << '\n';
    std::cout << *p;

    delete p;
}

This may not answer your question but it might illustrate why this is not working how you expect.这可能无法回答您的问题,但它可能会说明为什么这不符合您的预期。 When you call a member function of a class, ie classname::function() , you need to have an instance of that class on which to call it.当您调用类的成员函数时,即classname::function() ,您需要有该类的实例来调用它。 Something which has been defined like已经定义的东西

class classname {
public:
    classname() {ptr = new int(0);}
    size_t* function();
    ~classname();

    int* ptr;
};

size_t* classname::classfunction() {
    size_t* ptr = new size_t();
    return ptr;
}

Cannot be called by不能被调用

classname * p_p = classfunction();

because classfunction() is not being called on an instance of classname and because classname is not size_t so you can't assign classname to the return from a function which returns type size_t unless a cast from one to the other has been explicitly defined (same goes for classname* and size_t* ).因为classfunction()没有在classname的实例上被调用,并且因为classname不是size_t所以你不能将classname分配给返回类型size_t的函数的返回值,除非已经明确定义了从一个到另一个的强制转换(相同用于classname*size_t* )。 You can do something like this你可以做这样的事情

classname cls;
size_t* ptr = cls.classfunction();

Also note that destructors are not used for member functions, only for classes, so the syntax ~size_t*class::function() doesn't really make sense.另请注意,析构函数不用于成员函数,仅用于类,因此语法~size_t*class::function()没有真正意义。

If you are trying to get a pointer to a class instance you can simply do如果您试图获取指向类实例的指针,您可以简单地执行

classname * ptr = new classname();

and put your //... do something ... in a constructor.并把你的//... do something ...放在一个构造函数中。

Edit编辑

The use of a destructor is to perform the 析构函数的用途是执行

[...] necessary cleanup needed by a class when its lifetime ends. [...] 类在其生命周期结束时需要进行必要的清理。

This means that the destructor is called when the instance of said class goes out of scope or is manually deleted.这意味着当所述类的实例超出范围或被手动删除时,会调用析构函数。 So when you have a class defined as above, with the destructor所以当你有一个如上定义的类时,使用析构函数

classname::~classname() {
    delete ptr;
}

This means that ptr will be deleted when the instance of classname reaches the end of its "lifetime".这意味着当classname的实例达到其“生命周期”的末尾时, ptr将被删除。 Eg例如

int main() {
   classname* cls = new classname();
   // cls->ptr == int(0)
   delete cls; // Calls ~classname()
   // cls->ptr == NULL
}

The same is true for stack allocation ( classname cls(); ) and in either case the destructor would be called automatically at the end of main (if that instance had not already been manually deleted).堆栈分配( classname cls(); )也是如此,无论哪种情况,析构函数都会在main的末尾自动调用(如果该实例尚未被手动删除)。

Now what you can't do is delete a pointer that was allocated outside the class instance - if you want to be able to control a pointer like that while still having it accessible from outside the class you can make it a public member, as I did in the edited class declaration.现在不能做的是delete一个在类实例之外分配的指针 - 如果你希望能够控制这样的指针,同时仍然可以从类外部访问它,你可以使它成为公共成员,就像我一样在编辑过的类声明中做了。 This allows you to access the pointer from outside the class and then still delete it with the destructor,这允许您从类外部访问指针,然后仍然使用析构函数删除它,

int main() {
    classname* cls = new classname();
    // cls->ptr == 0
    cls->ptr = 3;
    // cls->ptr == 3
    delete cls;
    // cls->ptr == NULL
}

Hopefully that offers some clarity.希望这提供了一些清晰度。


The warning is because of the constructor警告是因为构造函数

*classname_c::classname_c(int value) {//...}

.... don't do this until you really know what you're doing, if you want a pointer to an instance of the class the constructor should be ....在你真正知道你在做什么之前不要这样做,如果你想要一个指向类实例的指针,构造函数应该是

classname_c::classname_c(int value) {//...}

and you should create the instance with你应该用

classname_c* cls = new classname_c(value);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM