簡體   English   中英

重載“ =”運算符時無法將數組元素分配給類變量

[英]Can't assign array element to class variable while overloading “=” operator

我是C ++編程的新手,所以也許這就是為什么我無法弄清楚為什么此分配不起作用的原因。 在我的課堂上,我想重載“ =”運算符。 我指定了一個函數,該函數將變量輸出為數組。 在重載中,我想將這些變量分配給新對象。

 obj_new = obj_with_variables

重載:

  obj_new_x=obj_with_values_parameters()[0];
  obj_new_y=obj_with_values_parameters()[1];

這是一個代碼:

// Test1.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include "string"

using namespace std;

class Vector2D
{
public:
Vector2D()
{

}
Vector2D(int& a, int& b)
    :x(a), y(b)
{

}
void Drukuj()
{
    cout << "wektor [" << x << ',' << y << "] \n";
}
void Wspolrzedne(int&a, int&b)
{
    x = a;
    y = b;
}
int* Wspolrzedne()
{
    int tab[2] = { x,y };
    return tab;
}
void operator = (Vector2D& obj)
{
    int* a = obj.Wspolrzedne();
    cout << a[0] << "\n";
    x = a[0];
    cout << x << " what? \n";
    y = a[1];
}

private:
int x, y;

};


int main()
{
int x1 = 2, x2 = 3;
Vector2D wektor(x1, x2);
wektor.Drukuj();
Vector2D wektor2;
wektor2 = wektor;
wektor2.Drukuj();
wektor.Drukuj();


return 0;
}

問題在於它分配了一些奇怪的值。 但是,如果我不使用引用,而是聲明2個int值(j,k)並將數組元素分配給它們[0,1],則效果很好。 同樣,當使用靜態數字(例如,代替a [0];使用“ 2”)時,它也可以正常工作。
到底是怎么回事?
如果有人能指出正確的答案/資源,我將感到非常高興。
問候,

在成員函數int* Wspolrzedne() ,返回本地變量tab的地址。 正如您在=運算符中所做的那樣,一旦變量的生存期結束就訪問該變量是undefined behavior

您的代碼具有未定義的行為,因為operator=正在訪問無效數據。 Wspolrzedne()返回的指針指向一個局部變量tab ,當Wspolrzedne()退出時,該tab超出范圍,因此operator=使用a指針未指向有效數據。

如果希望Wspolrzedne()返回多個值,則需要讓它返回(按值) structclass的實例以保存它們。 嘗試更多類似這樣的方法:

#include "stdafx.h"
#include <iostream>
#include <string>

using namespace std;

struct Coordinate {
    int x;
    int y;
};

class Vector2D
{
public:
    Vector2D()
        : x(0), y(0)
    {
    }

    Vector2D(int a, int b)
        : x(a), y(b)
    {
    }

    Vector2D(const Coordinate &c)
        : x(c.x), y(c.y)
    {
    }

    Vector2D(const Vector2D &src)
        : x(src.x), y(src.y)
    {
    }

    void Drukuj()
    {
        cout << "wektor [" << x << ',' << y << "] \n";
    }

    void Wspolrzedne(int a, int b)
    {
        x = a;
        y = b;
    }

    void Wspolrzedne(const Coordinate &c)
    {
        x = c.x;
        y = c.y;
    }

    Coordinate Wspolrzedne()
    {
        Coordinate c = { x, y };
        return c;
    }

    Vector2D& operator=(const Vector2D &obj)
    {
        Coordinate c = obj.Wspolrzedne();
        cout << c.x << ',' << c.y << "\n";
        Wspolrzedne(c);
        return *this;
    }

private:
    int x;
    int y;
};

另一方面,當可以直接訪問obj.xobj.y時,甚至沒有真正的理由甚至需要operator=調用Wspolrzedne()來獲取坐標:

Vector2D& operator=(const Vector2D &obj)
{
    x = obj.x;
    y = obj.y;
    return *this;
}

在這種情況下,您可以簡單地完全消除您的operator= ,然后讓編譯器提供默認生成的實現,為您執行完全相同的操作。

您的接口很危險,因為從函數返回原始指針意味着調用者必須知道如何管理它。 也就是說,調用者需要敏銳地意識到以下問題的答案:“調用者應該刪除指針,還是我從中獲得的對象保留所有權?” 該指針指向什么? 如果是數組,那么現在有很多元素嗎? 如果必須刪除它,是否使用delete或delete []?

等等。 這不好,因為它非常非常容易出錯。

接下來,您將具有一個函數,該函數返回指向堆棧本地數據的指針。 當函數返回時,該內存已經無效,因此返回值將始終導致未定義的行為讀取。

int* Wspolrzedne()
{
    int tab[2] = { x,y };    
    return tab;  // BAD - returns pointer to function stack data
}

標簽在哪里住? 當函數退出時,它會被銷毀,但是您要返回一個指向它的指針。

這是一個危險的界面,應進行更改。 也許您應該成對返回這些值:

std::pair<int, int> Wspolrzedne()
{
    return std::pair{ x,y }; // assuming c++17
    // return std::pair<int, int>{x, y}; // older compilers
}

這樣的接口避免了指針,並消除了上面提到的所有問題。

暫無
暫無

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

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