Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ.

Γεια σας. Ασχολούμαι μόνος μου με κάτι ασκήσεις που μας έδωσαν από τη σχολή στη C++ και επειδή τώρα μαθαίνω Operator overloading έχω κάποια θεματάκια και θέλω όποιος γνωρίζει να με βοηθήσει. Ανεβάζω την εκφώνηση και τη λύση μου.

 

Έστω η παρακάτω κλάση η οποία υλοποιεί την έννοια του γεωμετρικού κύκλου:

#define PI 3.14159265 
class Circle{ 
private: 
   float radius; 
public: 
   Circle() {radius=0;} 
   Circle(float r) {radius = r;} 
   float getPerimeter(){return (2*PI*radius);} 
   float getArea(){return (PI*radius*radius);} }; 

Να γίνει υπερφόρτωση του τελεστή εισαγωγής, ώστε τα αντικείμενα της κλάσης Circle να τυπώνονται στην οθόνη χρησιμοποιώντας την cout. Κατά την εκτύπωση θα πρέπει να εμφανίζονται στην οθόνη: η ακτίνα, η περίμετρος και το εμβαδό του κύκλου. (Σημείωση: Δεν επιτρέπεται αλλαγή του χαρακτηρισμού ασφάλειας της radius, ή η δήλωση επιπλέον βοηθητικών συναρτήσεων).

 

Οπότε εγώ έφτιαξα τρία διαφορετικά αρχεία (main, Circle header, Circle cpp) και έγραψα τα εξής:

#include <iostream>
#include <string>
#include "Circle.h"
using namespace std;

int main(){
Circle object4(10);
<<object4; //Dokimasa kai cout << object4;
return 0;
}
#ifndef CIRCLE_H
#define CIRCLE_H

class Circle{
private:
    float radius;
public:
    //CONSTRUCTORS
    Circle();
    Circle(float);
    ~Circle();
    //METHODS
    float getPerimeter();
    float getArea();
    Circle operator<<(Circle);
};

#endif

#include "Circle.h"
#include <iostream>
#include string
using namespace std;

Circle::Circle(){
 radius = 0;
}

Circle::Circle(float r){
 radius = r;
}

Circle::~Circle(){
 cout << "Object destructed" << endl;
}

float Circle::getPerimeter(){
 return 2*3.14159265*radius;
}

float Circle::getArea(){
 return 3.14159265*radius*radius;
}

Circle Circle::operator<<(Circle obj){
 cout << obj.radius;
 cout << obj.getPerimeter();
 cout << obj.getArea();
 return obj;
}

Τι κάνω λάθος στη main; Πως υπερφορτώνω έναν μονομελή τελεστή; Γενικά, ξέρω να υπερφορτώνω τον τελεστή αθροίσματος για να «προσθέσω» δύο αντικείμενα (π.χ Vectors) αλλά πως το κάνω αντίστοιχα εδώ;

 

ΥΓ: Όχι πως έχει ουσιώδη σημασία αλλά μήπως ο τελεστής εισαγωγής είναι >> αντί για <<;

  • Moderators
Δημοσ.

Δεν κάνεις overload τον operator<< του Circle, πρέπει να κάνεις overload τον operator<< του cout έτσι ώστε να δέχεται το Circle (το ποιος είναι αυτός ακριβώς το αφήνω σε σένα).

Δημοσ.

Μπορώ να έχω καμία extra υπόδειξη γιατί εξακολουθώ να μη καταλαβαίνω τι πρέπει να κάνω; 

Δημοσ.

Overloading...

#include <iterator>
#include <vector>
#include <iostream>
#include <string>
#include <algorithm>


struct foo
{
	int value;
	foo(int value) : value(value)
	{

	}
};


int Add(const int& left, const int& right)
{
	return left + right;
}
foo Add(const foo& left, const foo& right)
{
	return left.value + right.value;
}

int main(int argc, char **argv)
{
	int r1 = Add(1, 2); // r1 = 3;
	foo r2 = Add(foo(1), foo(2));// r2 = foo.value = 3
	return 0;
}

Μια συναρτηση μπορει να υλοποιηθει με διαφορους τροπους βαση των παραμετρων.

 

 

Τι γινεται αν το value δεν ειναι public;

#include <iterator>
#include <vector>
#include <iostream>
#include <string>
#include <algorithm>


struct foo
{
private:
	int value;
public:
	foo(int value) : value(value)
	{

	}
};


int Add(const int& left, const int& right)
{
	return left + right;
}
foo Add(const foo& left, const foo& right)
{
	return left.value + right.value;
}

int main(int argc, char **argv)
{
	int r1 = Add(1, 2); // r1 = 3;
	foo r2 = Add(foo(1), foo(2));// r2 = foo.value = 3
	return 0;
}

αυτο

Severity	Code	Description	Project	File	Line	Suppression State
Error	C2248	'foo::privateValue': cannot access private member declared in class 'foo'	test	c:\users\papi\documents\visual studio 2015\projects\test\test\source.cpp	18	

κανοντ αξες πραιβετ μεμπερ λεει, no shit

 

Αρα πρεπει να πουμε στη foo πως η add μπορει να κανει αξες τις μη παμπλικ παπαριες που εχει η foo. Αυτο το κανουμε πολυ απλα λεγοντας πως η add ειναι φιλη μας. (πραγματικα ομως :P )

struct foo
{
	friend foo Add(const foo&, const foo&);
private:
	int value;
public:
	foo(int value) : value(value)
	{

	}
};


int Add(const int& left, const int& right)
{
	return left + right;
}
foo Add(const foo& left, const foo& right)
{
	return left.value + right.value;
}

int main(int argc, char **argv)
{
	int r1 = Add(1, 2); // r1 = 3;
	foo r2 = Add(foo(1), foo(2));// r2 = foo.value = 3
	return 0;
}
 

ας παμε λιγο πιο κοντα στο προβλημα σου.

#include <iterator>
#include <vector>
#include <iostream>
#include <string>
#include <algorithm>


struct foo
{
	friend void Print(std::ostream&, const foo&);
private:
	int value;
public:
	foo(int value) : value(value)
	{

	}
};

void Print(std::ostream& left, const foo& right)
{
	left << right.value;
}

int main(int argc, char **argv)
{
	Print(std::cout, foo(2));
	
	return 0;
}

Ελπιζω να σας εχουν πει πως το std::cout ειναι ενα ostream object. 

 

Τωρα ας επιστρεψουμε ενα reference του ostream απο την print ωστε να μπορουμε να κανουμε κατι τετοιο

#include <iterator>
#include <vector>
#include <iostream>
#include <string>
#include <algorithm>


struct foo
{
	friend std::ostream& Print(std::ostream&, const foo&);
private:
	int value;
public:
	foo(int value) : value(value)
	{

	}
};

std::ostream& Print(std::ostream& left, const foo& right)
{
	left << right.value;
	return left;
}

int main(int argc, char **argv)
{
	Print(
		Print(std::cout, foo(2)),
		foo(3)
		);
	
	return 0;
}

wow το Print γραφει στο ostream (std::cout) το foo(2) και επιστρεφει ενα reference στην εξω print η οποια γραφει σε αυτο το reference το foo(3)

 

 

Ξερεις, δεν μ'αρεσει το Print, θα αλλαξω ονομα σε operator, 

#include <iterator>
#include <vector>
#include <iostream>
#include <string>
#include <algorithm>


struct foo
{
	friend std::ostream& operator,(std::ostream&, const foo&);
private:
	int value;
public:
	foo(int value) : value(value)
	{

	}
};

std::ostream& operator,(std::ostream& left, const foo& right)
{
	left << right.value;
	return left;
}

int main(int argc, char **argv)
{
	operator,(
		operator,(std::cout, foo(2)),
		foo(3)
		);
	
	return 0;
}

yeap its work

 

Μια στιγμη, το operator, ειναι το comma operator αρα μπορω να αλλαξω την main

#include <iterator>
#include <vector>
#include <iostream>
#include <string>
#include <algorithm>


struct foo
{
	friend std::ostream& operator,(std::ostream&, const foo&);
private:
	int value;
public:
	foo(int value) : value(value)
	{

	}
};

std::ostream& operator,(std::ostream& left, const foo& right)
{
	left << right.value;
	return left;
}

int main(int argc, char **argv)
{
	/*
	operator,(
		operator,(std::cout, foo(2)),
		foo(3)
		);
	*/
	std::cout, foo(2), foo(3);
	return 0;
}

Ααααα τωρα μαλιστα.

Credits στα μπιρονια.

  • Like 5
Δημοσ.

 

Ναι, ωραία η ειρωνεία αλλά άμα είχες διαβάσει τι είχα γράψει προσπαθούσα να κάνω overload το << , όχι τη cout. Άρα, όταν το googlαρα έγραφα overload <<. Δοκίμασε να το googlαρεις και σφύρα μου αν βγάλει αυτό που θες. ;)

 

Παπι μου φαίνονται πολύ παράξενα όλα αυτά που έγραψες. Θα κάτσω να τα ψάξω αύριο κ όχι δε μας έχουν πει αυτό για το ostream object. Ευχαριστώ πολύ!

Δημοσ.

Το ξέρω, δεν ήταν ό,τι καλύτερο μπορούσα να γράψω. Αλλά απλά πρέπει να μπεις στο σκεπτικό πως αν δεν σου βγαίνει με ένα query κάτι στο internet, να το προσπαθείς λίγο περισσότερο.

 

Π.χ. άμα βάλεις "cout custom class" είναι πάλι το πρώτο result (ή ακόμα και "cout class").

 

Anyway, enjoy τον κώδικα του παπιού.

Δημοσ.

Είναι παράξενα διότι η άσκηση είναι fail.

 

Πχ "υπερφόρτωση τελεστών εισαγωγής"

1) οι operators << και >> είναι shift operators

2) το cout είναι ostream o stream output stream. Εξάγει, δεν εισάγει.

 

Η σωστή διατύπωση είναι "να γίνει υπερφόρτωση της ostream::operator<<"

Ρίξε στο γκουγκλε το "ostream::operator<< overloading" να δεις πόσο ευστοχα αποτελέσματα θα έχεις.

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...