Jak prawidłowo przeciążyć operator
Piszę małą bibliotekę macierzową w C++ do operacji macierzowych. Jednak mój kompilator narzeka, gdzie wcześniej nie. Ten kod został pozostawiony na półce przez 6 miesięcy, a pomiędzy nimi zaktualizowałem mój komputer z debian etch do lenny (G++ (Debian 4.3.2-1.1) 4.3.2
) jednak mam ten sam problem na systemie Ubuntu z tym samym g++.
Oto odpowiednia część mojej klasy matrix:
namespace Math
{
class Matrix
{
public:
[...]
friend std::ostream& operator<< (std::ostream& stream, const Matrix& matrix);
}
}
I "realizacja":
using namespace Math;
std::ostream& Matrix::operator <<(std::ostream& stream, const Matrix& matrix) {
[...]
}
Jest to błąd podany przez kompilator:
Matrix.cpp: 459: error: 'std:: ostream&
Math:: Matrix:: operator
Jestem trochę zdezorientowany tym błędem, ale znowu mój C++ trochę zardzewiał po zrobieniu wielu Javy przez te 6 miesięcy. :-)
187
Author: Agnel Kurian, 2009-01-24
5 answers
Zadeklarowałeś swoją funkcję jako friend
. Nie należy do klasy. Należy usunąć Matrix::
z implementacji. friend
oznacza, że określona funkcja (która nie jest członkiem klasy) może uzyskać dostęp do prywatnych zmiennych członkowskich. Sposób w jaki zaimplementowałeś tę funkcję jest jak metoda instancji dla klasy Matrix
, która jest błędna.
107
Author: Mehrdad Afshari,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-24 16:37:35
Mówię ci o jeszcze jednej możliwości: lubię używać do tego definicji przyjaciół:
namespace Math
{
class Matrix
{
public:
[...]
friend std::ostream& operator<< (std::ostream& stream, const Matrix& matrix) {
[...]
}
};
}
Funkcja będzie automatycznie kierowana do otaczającej przestrzeni nazw Math
(nawet jeśli jej definicja pojawia się w zakresie tej klasy), ale nie będzie widoczna, chyba że wywołasz operatorMath::Matrix<TypeA, N>.
126
Author: Johannes Schaub - litb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-24 22:28:38
Aby dodać do Mehrdad odpowiedź,
namespace Math
{
class Matrix
{
public:
[...]
}
std::ostream& operator<< (std::ostream& stream, const Math::Matrix& matrix);
}
W Twojej implementacji
std::ostream& operator<<(std::ostream& stream,
const Math::Matrix& matrix) {
matrix.print(stream); //assuming you define print for matrix
return stream;
}
65
Author: kal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-24 19:00:05
Zakładając, że mówimy o przeciążeniu operator <<
dla wszystkich klas wywodzących się z std::ostream
do obsługi klasy Matrix
(i nie przeciążeniu <<
dla klasy Matrix
), bardziej sensowne jest zadeklarowanie funkcji przeciążenia poza przestrzenią nazw w nagłówku.
Użyj funkcji friend tylko wtedy, gdy nie można jej osiągnąć za pomocą publicznych interfejsów.
Matrix.h
namespace Math {
class Matrix {
//...
};
}
std::ostream& operator<<(std::ostream&, const Math::Matrix&);
Zauważ, że przeciążenie operatora jest deklarowane poza przestrzeń nazw.
Matrix.cpp
using namespace Math;
using namespace std;
ostream& operator<< (ostream& os, const Matrix& obj) {
os << obj.getXYZ() << obj.getABC() << '\n';
return os;
}
Z drugiej strony, jeśli twoja funkcja przeciążenia robi musi zostać zaprzyjaźniona, tzn. potrzebuje dostępu do prywatnych i chronionych członków.
Matematyka.h
namespace Math {
class Matrix {
public:
friend std::ostream& operator<<(std::ostream&, const Matrix&);
};
}
Musisz załączyć definicję funkcji blokiem przestrzeni nazw zamiast using namespace Math;
.
Matrix.cpp
using namespace Math;
using namespace std;
namespace Math {
ostream& operator<<(ostream& os, const Matrix& obj) {
os << obj.XYZ << obj.ABC << '\n';
return os;
}
}
55
Author: sanjivr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-15 14:10:27
W C++14 możesz użyć następującego szablonu, aby wydrukować dowolny obiekt, który ma element t::print (std::ostream&)const;.
template<class T>
auto operator<<(std::ostream& os, const T& t) -> decltype(t.print(os), os)
{
t.print(os);
return os;
}
25
Author: QuentinUK,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-05 08:24:36
Piszę małą bibliotekę macierzową w C++ do operacji macierzowych. Jednak mój kompilator narzeka, gdzie wcześniej nie. Ten kod został pozostawiony na półce przez 6 miesięcy, a pomiędzy nimi zaktualizowałem mój komputer z debian etch do lenny (G++ (Debian 4.3.2-1.1) 4.3.2 ) jednak mam ten sam problem na systemie Ubuntu z tym samym g++.
Oto odpowiednia część mojej klasy matrix:
namespace Math
{
class Matrix
{
public:
[...]
friend std::ostream& operator<< (std::ostream& stream, const Matrix& matrix);
}
}
I "realizacja":
using namespace Math;
std::ostream& Matrix::operator <<(std::ostream& stream, const Matrix& matrix) {
[...]
}
Jest to błąd podany przez kompilator:
Matrix.cpp: 459: error: 'std:: ostream& Math:: Matrix:: operator
Jestem trochę zdezorientowany tym błędem, ale znowu mój C++ trochę zardzewiał po zrobieniu wielu Javy przez te 6 miesięcy. :-)
5 answers
Zadeklarowałeś swoją funkcję jako friend
. Nie należy do klasy. Należy usunąć Matrix::
z implementacji. friend
oznacza, że określona funkcja (która nie jest członkiem klasy) może uzyskać dostęp do prywatnych zmiennych członkowskich. Sposób w jaki zaimplementowałeś tę funkcję jest jak metoda instancji dla klasy Matrix
, która jest błędna.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-24 16:37:35
Mówię ci o jeszcze jednej możliwości: lubię używać do tego definicji przyjaciół:
namespace Math
{
class Matrix
{
public:
[...]
friend std::ostream& operator<< (std::ostream& stream, const Matrix& matrix) {
[...]
}
};
}
Funkcja będzie automatycznie kierowana do otaczającej przestrzeni nazw Math
(nawet jeśli jej definicja pojawia się w zakresie tej klasy), ale nie będzie widoczna, chyba że wywołasz operatorMath::Matrix<TypeA, N>.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-24 22:28:38
Aby dodać do Mehrdad odpowiedź,
namespace Math
{
class Matrix
{
public:
[...]
}
std::ostream& operator<< (std::ostream& stream, const Math::Matrix& matrix);
}
W Twojej implementacji
std::ostream& operator<<(std::ostream& stream,
const Math::Matrix& matrix) {
matrix.print(stream); //assuming you define print for matrix
return stream;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-24 19:00:05
Zakładając, że mówimy o przeciążeniu operator <<
dla wszystkich klas wywodzących się z std::ostream
do obsługi klasy Matrix
(i nie przeciążeniu <<
dla klasy Matrix
), bardziej sensowne jest zadeklarowanie funkcji przeciążenia poza przestrzenią nazw w nagłówku.
Użyj funkcji friend tylko wtedy, gdy nie można jej osiągnąć za pomocą publicznych interfejsów.
Matrix.h
namespace Math {
class Matrix {
//...
};
}
std::ostream& operator<<(std::ostream&, const Math::Matrix&);
Zauważ, że przeciążenie operatora jest deklarowane poza przestrzeń nazw.
Matrix.cpp
using namespace Math;
using namespace std;
ostream& operator<< (ostream& os, const Matrix& obj) {
os << obj.getXYZ() << obj.getABC() << '\n';
return os;
}
Z drugiej strony, jeśli twoja funkcja przeciążenia robi musi zostać zaprzyjaźniona, tzn. potrzebuje dostępu do prywatnych i chronionych członków.
Matematyka.h
namespace Math {
class Matrix {
public:
friend std::ostream& operator<<(std::ostream&, const Matrix&);
};
}
Musisz załączyć definicję funkcji blokiem przestrzeni nazw zamiast using namespace Math;
.
Matrix.cpp
using namespace Math;
using namespace std;
namespace Math {
ostream& operator<<(ostream& os, const Matrix& obj) {
os << obj.XYZ << obj.ABC << '\n';
return os;
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-15 14:10:27
W C++14 możesz użyć następującego szablonu, aby wydrukować dowolny obiekt, który ma element t::print (std::ostream&)const;.
template<class T>
auto operator<<(std::ostream& os, const T& t) -> decltype(t.print(os), os)
{
t.print(os);
return os;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-05 08:24:36