[英]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();
我正在學習 C++ 中的類/析構函數,並且需要從類成員返回指針:
size_t * classname :: function();
但它不起作用。
我的邏輯是聲明一個類變量,例如classname * p_p = classfunction(data);
應該訪問類成員:
size_t * classname :: classfunction(data)
{
//... do something ...
new p_p;
return p_p;
}
因此,每次調用類的成員函數時,理論上的指針地址都會返回到main()
變量p_p
。 或者應該但不應該並且程序以某種方式崩潰但甚至不確定在哪一點。
沒有編譯器警告或錯誤,調試器不會在任何地方停止,而且我根本沒有發現從類成員函數返回指針的任何內容,也沒有發現它是不允許的或什么的。
此外,如果有一種語法可以從類成員函數返回指針,我將需要一種語法來刪除“ 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);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.