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



我正在学习 c++ 中的类/析构函数,并且需要从类成员返回指针:

size_t * classname :: function();

但它不起作用。

我的逻辑是声明一个类变量,例如 应访问类成员classname * p_p = classfunction(data);

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

因此,理论上,每次调用类的成员函数时,指针地址都会p_p返回到main()变量。 或者应该但不是,程序以某种方式崩溃,但甚至不确定在哪一点上。

没有编译器警告或错误,并且 调试器不会在任何地方停止,我根本没有发现从类成员函数返回指针的内容,也没有发现它不是被允许的或其他东西。

此外,如果有语法从类成员函数返回指针,我需要有一个语法来删除"new p_p"。

所以我的问题是:它应该工作吗,我将如何让它运行,或者为什么它可能不起作用或被禁止?在我的逻辑中,这应该是一种正确的方法,但我可能以某种方式错了,并且类并不完全支持此功能。

编辑:

感谢您的回答和评论,我得到了从班级成员返回的指针。(也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;
}

带来以下输出:

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...

现在我不确定 ~destructor 是否/何时工作,或者我如何测试我是否创建了析构函数权限,因为 ptr 值没有被删除。 我也可以修复

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

从成员函数返回指针是完全可以的,尽管返回指向已分配size_t的指针似乎有点矫枉过正。

你想要的可能是这样的:

#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;
}

这可能无法回答您的问题,但它可能会说明为什么这不能按您的预期工作。当您调用类的成员函数时,即classname::function(),你需要有一个要调用它的类的实例。已被定义的东西,例如

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;
}

无法由 调用

classname * p_p = classfunction();

因为classfunction()不是在classname实例上调用的,并且因为classname不是size_t所以你不能classname分配给返回类型size_t的函数的返回,除非已经显式定义了从一个到另一个的强制转换(classname*size_t*也是如此(。你可以做这样的事情

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

另请注意,析构函数不用于成员函数,仅用于类,因此语法~size_t*class::function()实际上没有意义。

如果你试图获取一个指向类实例的指针,你可以简单地做

classname * ptr = new classname();

并将//... do something ...放在构造函数中。

编辑

析构函数的使用是为了执行

[...]当一个类的生命周期结束时,需要必要的清理。

这意味着当所述类的实例超出范围或被手动删除时,将调用析构函数。因此,当您具有如上所述定义的类时,使用析构函数

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

这意味着当classname实例达到其"生存期"结束时,ptr将被删除。

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

堆栈分配(classname cls();(也是如此,在任何一种情况下,析构函数都将在main结束时自动调用(如果该实例尚未手动删除(。

现在你不能做的是delete一个在类实例外部分配的指针 - 如果你想能够像这样控制一个指针,同时仍然可以从类外部访问它,你可以让它成为一个公共成员,就像我在编辑的类声明中所做的那样。这允许您从类外部访问指针,然后仍然使用析构函数将其删除,

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

希望这能提供一些清晰度。


警告是因为构造函数

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

....在你真正知道你在做什么之前不要这样做,如果你想要一个指向类实例的指针,构造函数应该是

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

您应该使用

classname_c* cls = new classname_c(value);

相关内容

最新更新