Przeładownie operatora=

0

Witam,

mam sobie klasę extLong, która zajmuje się przechowywaniem dużych liczb w postaci stringów:

 
class extLong
{
	public:
		string str;		// przechowywana liczba w postaci stringa
//...
};

oraz przeładowałem sobie operator= dla long longów:

 
extLong extLong::operator=(long long b)
{
	str = itoa(b);
	return *this;
}

gdzie

 itoa()

jest funkcją konwertującą nam long longi na stringi
Mogę dzięki temu wykonać taką operację przypisania:

extLong a;
a = 23;

ale nie mogę już zrobić tego przy deklaracji zmiennej:

 
extLong a = 23;

otrzymuję błąd:

[Error] conversion from 'int' to non-scalar type 'extLong' requested

W jaki sposób mam przeładować operator=, aby taka operacja była możliwa ?

2

Nie wiem czy czegoś nie pokręcę, ale w tym wypadku ma miejsce copy initialization. Żeby to zadziałało musisz stworzyć konstruktor, który przyjmuje long long czyli

class extLong
{
public:
	extLong( const long long v ) : str( std::to_string( v ) )
	{}

    string str;        // przechowywana liczba w postaci stringa
//...
};
2

To: extLong a = 23;
Zamienia się na extLong a(23); - czytaj o copy elsion: https://en.wikipedia.org/wiki/Copy_elision

Lepiej zrób zamiast tego operatora = konstruktor z long long (jak pisze @stryku wyżej) wtedy będzie działać w obu przypadkach.

0

Dzięki wielkie, działa :)

Mam jeszcze 2 pytania co do tego tematu:

PIERWSZE: Jak zrobić żeby obiekt klasy extLong mógł mieć sens logiczny? Mogę zrobić coś takiego:

 
int zmienna = 1;
if(zmienna) wykonajcos();

Jak sprawić, abym mógł w ten sam sposób użyć obiektu klasy extLong?

DRUGIE: Chciałem aby nowy typ danych jaki stworzyłem extLong, był kompatybilny z typami long long oraz string. W tym celu przeładowałem prawie wszystkie operatory matematyczne i logiczne, tak abym mógł pracować zamiennie na liczbach zapisanych jako extLong, long long czy string. Zrobiłem to raz jako składowe klasy extLong, więc mogłem używać przypisania extLong = long long, zrobiłem wszystkie pozostałe operatory w drugą stronę, czyli jako luźne funkcje np. dodające long long + extLong. Nie udało mi się tylko zrobić operatorów przypisania dla: long long = extlong oraz string = extLong:

string operator=(string a, extLong b)
{
	a = b.str;
	return a;
}
long long operator=(long long a, extLong b)
{
	a = atoi(b.str.c_str());
	return a;
}

Dostaję błędy:

[Error] 'std::string operator=(std::string, extLong)' must be a nonstatic member function
[Error] 'long long int operator=(long long int, extLong)' must be a nonstatic member function

Rozumiem, że skoro do przypisania wartości zmiennej podczas jej deklaracji musiałem dołożyć nowy konstruktor, to na wykonanie czegoś takiego nie ma szans?

extLong ext = 24343252;
string s = ext;

Pozdrawiam

2
#include <iostream>
#include <string>
using namespace std;

struct X
{
	explicit operator bool() { return true; }
	operator string() { return "To dziala dzieki operator string()\n"; }
};

int main() 
{
	X x;
	if (x) 
		cout << "To dziala dzieki operator bool()\n";
		
	string s = x;
	cout << s;
	
	return 0;
}
0
twonek napisał(a):
#include <iostream>
#include <string>
using namespace std;

struct X
{
	explicit operator bool() { return true; }
	operator string() { return "To dziala dzieki operator string()\n"; }
};

int main() 
{
	X x;
	if (x) 
		cout << "To dziala dzieki operator bool()\n";
		
	string s = x;
	cout << s;
	
	return 0;
}

To co podałeś działa, jednak jeśli w mojej klasie znajdą się jakieś inne operatory dla innych typów w tym samym celu co operator dla stringa, zaczyna się problem z przeładowaniem nazw operatora=

 
struct klasa
{
	string str;
	operator string()
	{
		return str;
	}
	operator long long();
	operator int();
	explicit operator bool();
};

Przypisanie wartości zmiennej s podczas jej deklaracji działa:

 
klasa a;
a.str = "23";

string p = a;

Natomiast samo przypisanie

 
klasa a;
a.str = "23";

string s;
s = a;

daje błąd:

In function 'int main()':
[Error] ambiguous overload for 'operator=' (operand types are 'std::string {aka std::basic_string<char>}' and 'klasa')
[Note] candidates are:
In file included from C:/Program Files (x86)/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include/c++/string
from C:/Program Files (x86)/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include/c++/bits/locale_classes.h
from C:/Program Files (x86)/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include/c++/bits/ios_base.h
from C:/Program Files (x86)/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include/c++/ios
from C:/Program Files (x86)/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include/c++/ostream
from C:/Program Files (x86)/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include/c++/iostream
from C:\Users\qwetiio\Desktop\extLongtest.cpp
[Note] std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT, _Traits, _Alloc>::operator=(const std::basic_string<_CharT, _Traits, _Alloc>&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]
[Note] std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT, _Traits, _Alloc>::operator=(const _CharT*) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>] <near match="match">
[Note] no known conversion for argument 1 from 'klasa' to 'const char*'
[Note] std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT, _Traits, _Alloc>::operator=(_CharT) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]

0

Wstaw przed jednym z nich klauzule explicit.

0

Wtedy nie będę mógł ich używać. Chcę wykonywać operacje takie jak:

 
klasa a;

int c = a;
c = a;

long long b = a;
b = a;

string s = a;
s = a;
0

będziesz mógł, ale z głową:

klasa a;
int c = a; // tu i tak działa konstruktor int c(a);
c = (int)a;
long long b = a; // tu i tak działa konstruktor long long b(a);
b = (long long)a;
string s = a; // tu i tak działa konstruktor string s(a);
s = (string)a;
0

A nie da się w żaden sposób doprowadzić do możliwości stosowania najprostszego zapisu a = b ?

0

Da się, konwertuj tylko na jeden typ numeryczny (oraz z niego) czyli long long

0

Tzn co ? A co ze stringiem ? Sprowadźmy to tylko do stringa i long longa. Jak mogę to zrealizować ?

0

Gdzie widzisz problem?

#include <string>
#include <iostream>
using namespace std;

class foo
  {
   public:
   foo(long long) {}
   foo(const string &) {}
   operator long long()const { return 666; }
   explicit operator string()const { return "666"; }
  };

int main()
  {
   string s("abc");
   long long v=13;
   
   foo fa(s),fb=s,fc(v),fd=v;
   s=fc;
   v=fa;   
   return 0;
  }
0

To co napisałeś nie działa tak jak powinno. Już trudno, obecnie jedynego zapisu którego nie mogę przeprowadzić tak jak chciałem jest:

 
klasa a;
string s;
s = a;

Szkoda czasu na zabawę z taką pierdołą.

Temat wyczerpany. Dzięki za pomoc. :)
Pozdrawiam

1 użytkowników online, w tym zalogowanych: 0, gości: 1