[英]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()
返回多個值,則需要讓它返回(按值) struct
或class
的實例以保存它們。 嘗試更多類似這樣的方法:
#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.x
和obj.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.