簡體   English   中英

Visual Studio中C ++指針的問題(但可在g ++中使用)

[英]problem with c++ pointers in visual studio (but works in g++)

當我在Microsoft Visual Studio中運行以下代碼時,它會輸出垃圾值(內存地址?),但是當它在g ++中運行時,它會輸出我想要的值(有一些更改,例如更改srand)。 如何修復它以便在Visual Studio中工作? 我只有幾個月的編碼經驗,這個問題困擾了我一段時間。

class Vehicle
{
    protected:
        int * vin;
        double * gasMileage;

    public:
        Vehicle();
        Vehicle(int v, double g);

        virtual void display(){cout<<"vin: "<<*vin<<endl<<"gasMileage: " <<*gasMileage<<endl;}
        virtual double calcGasUsed(int milesDriven){return *gasMileage * milesDriven;}

        int getVin(){return *vin;}
        double getGasMileage(){return *gasMileage;}

        void changeVin(int newvin) {vin=&newvin;}
        void changeGasMileage(double newGasMileage){gasMileage=&newGasMileage;}
        void drive();
};

class Suv:public Vehicle
{
    protected:
        bool *fourWDStatus;
        double * fourWDGasMileage;

    public:
        Suv();
        Suv(int v, double g,bool status, double fwdg);

        void display();
        double calcGasUsed(Suv&, int milesDriven);
        bool getFourWDStatus(){return *fourWDStatus;}
        double getfourWDGasMileage(){return *fourWDGasMileage;}

        void changeFourWDStatus(bool status) {fourWDStatus=&status;}
        void changeFourWDGasMileage(double newGasMileage){fourWDGasMileage=&newGasMileage;}

};
Vehicle::Vehicle()
{
    this->vin=0000;
    this->gasMileage=00;
}
Vehicle::Vehicle(int v, double g)
{
    this->vin=&v;
    this->gasMileage=&g;
}
Suv::Suv(int v, double g,bool status, double fwdg)
{
    this->vin=&v;
    this->gasMileage=&g;
    this->fourWDStatus=&status;
    this->fourWDGasMileage=&fwdg;
}
Suv::Suv()
{
    this->vin=0000;
    this->gasMileage=00;
    this->fourWDStatus=false;
    this->fourWDGasMileage=00;
}
void Suv::display()
{
    Vehicle::display();
    cout<<"fourWDStatus: "<<*fourWDStatus<<endl<<"fourWDGasMileage: "<<*fourWDGasMileage<<endl;
}
void Vehicle::drive()
{
    int r=rand()%10000;
    cout<<calcGasUsed(r)<<endl;

}
double Suv::calcGasUsed(Suv&, int milesDriven)
{
    double x;
    if (*fourWDStatus== true)
    {
        x= ((*fourWDGasMileage) * (milesDriven));
        return x;
    }
    else
    {
        x=((*gasMileage) * (milesDriven));
        return x;
    }
}

void main()
{
    cout << "test";
    srand(NULL);
    Suv A(300,12.2,false,16.6);
    Suv B(200,15.5,false,20.1);
    B.changeFourWDStatus(true);
    Vehicle C(111,20.5);
    C.drive();
    C.display();
    B.display();
    Vehicle arrOfCars[]={A,B,C};
    A.drive();
    B.drive();
    C.drive();
    system("pause");

}

您正在使用指針,而沒有將它們初始化為任何東西。 快速瀏覽對我說,您的成員變量都不應該是指針,構造函數的任何參數都不應該是引用。 在其他地方,您將int分配給int *。 編譯器是否向您發出警告?

還有另外兩個奇怪的事情:為什么對整數文字使用四位數的0000 ,為什么要使用system("pause")

不要將類的數據成員存儲為指針。 無需給出您的用法。 乍一看,我在這里看到了一個問題:

void changeGasMileage(double newGasMileage){gasMileage=&newGasMileage;}

這樣做是將gasMileage設置為指向在堆棧上分配的值。 changeGasMileage返回時,您不再知道該內存位置中的內容。 您可以只使gasMileage成為值而不是指針。 否則,您需要執行以下操作:

void changeGasMileage(double newGasMileage){gasMileage= new double(newGasMileage);}

成員Vehicle::vinVehicle::gasMileage以及Vehicle::gasMileage Suv::fourWDStatusSuv::fourWDGasMileage均未正確初始化。

從您發布的代碼看來,將它們從指針更改為常規變量(並適當地調整方法)似乎會更好。

編輯:如果使用指針是分配的一部分,則必須正確初始化它們。 在您的情況下,這意味着在構造函數中分配內存。 可能是這樣的:

Vehicle::Vehicle()
{
    this->vin = new int(0);
    this->gasMileage = new double(0.0);
}

Vehicle::Vehicle(int v, double g)
{
    this->vin = new int(v);
    this->gasMileage = new double(g);
}

Suv::Suv(int v, double g,bool status, double fwdg) : Vehicle(v, g)
{        
    this->fourWDStatus = new bool(status);
    this->fourWDGasMileage = new double(fwdg);
}

Suv::Suv() : Vehicle(0, 0.0)
{
    this->fourWDStatus = new bool(false);
    this->fourWDGasMileage = new double(0.0);
}

其他人介紹了在這種情況下不適合使用指針。 我同意。

同樣,當構造函數收到一個按值復制的值時,您要獲取的地址值位於(調用)堆棧上。 當該構造函數退出時,局部變量將被破壞(內置類型,int,char,float等通常為no-op),並且通過指針訪問它們是“未定義的行為”。

為什么這樣發生: 未定義的行為意味着任何事情都可以發生。 最好是編譯器診斷程序,或者是崩潰程序,或者更糟糕的是,它仍然可以看到為損壞的數據,但是最壞的情況是,巧合使它可以工作到以后的某個時間-另請參見“ 巧合編程”

一旦構造函數退出,該區域將在調用其他函數時開放供重用-他們將需要一個地方來存儲其局部變量,參數和參數/返回地址,以調用其他函數。

碰巧的是,gcc(該版本,那些編譯器標志)不會覆蓋堆棧上用於打印值的位置,因此,您讀取的值就是您期望的值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM