當我存盤一個普通int的A并執行一個簡單的 get 函式時:
#include <iostream>
class A
{
int p;
public:
void setint(int p_x);
int getint();
};
void A::setint(int p_x) {p = p_x;} // set p (type int)
int A::getint() {return p;} // get p (type int)
int main()
{
A arr_a[5];
arr_a[0].getint();
}
它編譯并退出代碼0。但是,當我更改int為int*并嘗試執行相同操作時:
#include <iostream>
class A
{
int* p;
public:
void setint(int p_x);
int getint();
};
void A::setint(int p_x) {*p = p_x;} // set int pointed to by p (type int)
int A::getint() {return *p;} // get int pointed to by p (type int)
int main()
{
A arr_a[5];
arr_a[0].getint();
}
它編譯良好,但退出代碼3221225477。為什么會這樣,是否還有一種方法可以將指標A存盤A在陣列中?
uj5u.com熱心網友回復:
你的程式有一個嚴重的缺陷。您給定的兩個代碼片段(您問題中的案例 1 和案例 2)都有未定義的行為。讓我們看看它是如何
案例一:代碼片段 1
在您的代碼片段 1 中,由于資料成員p是內置型別并且您尚未對其進行初始化,因此p具有垃圾值并且使用(訪問)此值可能會導致未定義的行為,這正是您的情況所發生的情況。
當你寫道:
A arr_a[5];//this creates a 1D array of size 5 having elements of type `A` but the elements are default initialized
arr_a[0].getint();//this result in undefined behavior
上面的陳述句創建了一個大小為 5 的一維陣列,其元素型別為A。的問題是,因為你沒有初始化該陣列中,其元素是預設初始化這意味著資料成員的值p也被預設初始化。但是由于您沒有為變數使用類內初始值設定項p,因此p具有垃圾值,這會導致未定義的行為。
您可以通過查看此處的輸出來確認這一點。
案例一的解決方案
您可以通過p使用類內初始化程式初始化資料成員來解決這個問題,如下所示:
#include <iostream>
class A
{
int p = 0;//USE IN-CLASS INITIALIZER
public:
void setint(int p_x);
int getint();
};
void A::setint(int p_x) {p = p_x;} // set p (type int)
int A::getint() {return p;} // get p (type int)
int main()
{
A arr_a[5];
std::cout<<arr_a[0].getint();//now ok because we have initilaized p
}
案例二:代碼片段2
在這種情況下,唯一的區別是現在資料成員p是一個指向 int 的指標,即int*. 與最后一種情況類似,指標變數有一個垃圾值,如果您嘗試像在主函式中那樣使用它,則可能會導致未定義的行為,如下所示:
A arr_a[5];//create a 1D array of objects `A` but the elements(A objects) are default initialized
arr_a[0].getint();//this result in undefined behavior
案例二的解決方案
您可以通過p使用類內初始化程式初始化資料成員來解決這個問題,如下所示:
#include <iostream>
class A
{
int* p = nullptr;//USE IN-CLASS INITIALIZER
public:
void setint(int p_x);
int getint();
};
void A::setint(int p_x) {*p = p_x;} // set int pointed to by p (type int)
int A::getint() {return *p;} // get int pointed to by p (type int)
int main()
{
A arr_a[5];
arr_a[0].getint();//now ok because we have initilaized p
}
概括
您提供的兩個代碼片段都有未定義的行為。您可以通過使用類內初始化程式將資料成員初始化p為默認值來解決這兩個問題。
uj5u.com熱心網友回復:
在您的第二種情況下,A arr_a[5]只需創建一個包含 5 個 A 的陣列。但對于每個 A,指標是一個未定義的數字(可能是 0x0),因此*p是未定義的行為。你應該像這樣在你的類中添加A::A()和A::~A()管理你的指標:
#include <iostream>
class A
{
int *p;
public:
A();
~A();
void setint(int p_x);
int getint();
};
A::A() : p(new int) {}
A::~A() { delete p; }
void A::setint(int p_x) { *p = p_x; } // set int pointed to by p (type int)
int A::getint() { return *p; } // get int pointed to by p (type int)
int main()
{
A arr_a[5];
arr_a[0].getint();
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/368446.html
上一篇:在Ruby中訪問超類中的子類變數
