Reputation: 131
I have a Java code; this my Poin Java code:
import java.util.Scanner;
public class Poin {
private int X;
private int Y;
public Poin() {
X = 0;
Y = 0;
}
public Poin(int X, int Y) {
this.X = X;
this.Y = Y;
}
public int getX() {
return X;
}
public int getY() {
return Y;
}
public boolean InRect(Poin TopLeft, Poin BottomRight) {
if (this.X < BottomRight.getX() && this.X > TopLeft.getX()
&& this.Y < BottomRight.getY() && this.Y > TopLeft.getY()) {
return true;
} else {
return false;
}
}
public static void main(String [] args) {
int N;
int i;
int x,y;
int count = 0;
Poin TopLeft, BottomRight;
Scanner sc = new Scanner(System.in);
N = sc.nextInt();
Poin[] a = new Poin[N];
int x_top = sc.nextInt();
int y_top = sc.nextInt();
int x_bot = sc.nextInt();
int y_bot = sc.nextInt();
TopLeft = new Poin(x_top, y_top);
BottomRight = new Poin(x_bot, y_bot);
for (i = 0; i < N; i++) {
x = sc.nextInt();
y = sc.nextInt();
Poin p = new Poin(x, y);
a[i] = p;
if (p.InRect(TopLeft, BottomRight)) {
count += 1;
}
}
System.out.println(count);
for (i = 0; i < N; i++) {
System.out.println(a[N-1-i].getX()+","+a[N-1-i].getY());
}
}
}
I want to convert this to c++. This is my c++ code:
#include <iostream>
#include <cstdlib>
using namespace std;
class Poin
{
private :
int x;
int y;
public :
Poin() {
x = 0;
y = 0;
}
Poin(int x, int y) {
this->x = x;
this->y = y;
}
int get_x() {
return x;
}
int get_y() {
return y;
}
bool InRect(Poin& TopLeft, Poin& BottomRight) {
if (this->x < BottomRight.get_x() && this->x > TopLeft.get_x() && this->y < BottomRight.get_y() && this->y > TopLeft.get_y())
{
return true;
}
else
{
return false;
}
}
};
int main ()
{
int N;
int i;
int x,y;
int count = 0;
int x_top;
int y_top;
int x_bot;
int y_bot;
Poin TopLeft, BottomRight;
Poin** a = new Poin*[N];
cin>>x_top;
cin>>y_top;
cin>>x_bot;
cin>>y_bot;
TopLeft = new Poin(x_top, y_top);
BottomRight = new Poin(x_bot, y_bot);
for (i = 0; i < N; i++) {
x = cin>>x;
y = cin>>y;
px = p.poin(x, y);
a[i] = p;
if (px.InRect(TopLeft, BottomRight)) {
count += 1;
}
}
cout<<count;
for (i = 0; i < N; i++) {
cout << a[N-1-i].getX() << "," << a[N-1-i].getY();
}
return 0;
}
I have difficulty converting this code from Java to c++. Poin is class and using this as parameter in main program:
Poin TopLeft, BottomRight;
TopLeft = new Poin(x_top, y_top);
BottomRight = new Poin(x_bot, y_bot);
Does anybody have a solution to solve my problem?
Upvotes: 0
Views: 2981
Reputation: 490108
While you've gotten some advice about the superficial problems you've seen, the result of following that advice (by itself) is still going to be what I'd consider poor C++ code. So far, you're basically transliterating from Java to C++, making roughly the smallest changes in syntax necessary to get a C++ compiler to accept what's still basically Java code.
I'd advise, instead, writing C++ that's really C++. It'll be quite different from your Java code, because fundamentally the two are really quite different languages, and code written to use C++ (at all) well is markedly different from code to do the same job in Java.
Let's consider the fundamentals of what your code really does, and write some C++ that does that.
int
s)We want to write the code to support that as cleanly as possible, so let's start with a poin
class that's properly defined for the job. The necessary capabilities are:
That should be all it needs, so let's just implement that:
class Poin {
int x;
int y;
public:
// construct a point from two ints. Note that we prefer to use the member
// initialization list over assigning inside the body of the ctor
Poin(int x=0, int y=0) : x(x), y(y) {}
bool operator<(Poin const &other) const {
return x < other.x && y < other.y;
}
bool in_rect(Poin const &TL, Poin const &BR) const {
return (*this < BR) && (TL < *this);
}
// read a Poin from a stream:
friend std::istream &operator>>(std::istream &is, Poin &p) {
return is >> p.x >> p.y;
}
// display a Poin on a stream. Note: operator>> won't read what this writes
friend std::ostream &operator<<(std::ostream &os, Poin const &p) {
return os << p.x << "," << p.y;
}
};
Note a few points (pardon the pun): we don't have/need/want a getX
or getY
or anything similar. A poin
knows how to handle its own I/O, so outside code just reads or writes a poin
-- it doesn't have to deal with the details of the x
and y
coordinates that make up a poin
. Likewise, a poin
"knows" how to compare itself to another poin
(in a way that fits our needs--certainly not the only possible way it could be defined though). We then use that to get a fairly simple definition of in_rect
.
Using that, along with the algorithms, iterators, and containers in the standard library, our main
becomes drastically simpler and cleaner:
int main() {
// read points defining the rectangle from standard input:
Poin TL, BR;
std::cin >> TL >> BR;
// read points from standard input to initialize collection:
std::vector<Poin> points{
std::istream_iterator<Poin>(std::cin),
std::istream_iterator<Poin>() };
// display count of points inside rectangle:
std::cout << "Count: "
<< std::count_if(points.begin(), points.end(),
[&](Poin const &p) { return p.in_rect(TL, BR); })
<< "\n";
// display all points in reverse order:
std::copy(points.rbegin(), points.rend(),
std::ostream_iterator<Poin>(std::cout, "\n"));
}
I've had to work hard to resist the temptation to expound on the superiority and simplicity of this code, and the advantages over a lower level language like Java, but I guess I'll let the code speak for itself on that subject.
I will add one final note though: this code is written in C++11. If you're using an older compiler, you may have trouble with a couple of points. Two obvious ones are the initialization of points
-- with an older compiler, you might need to change the syntax slightly, to:
std::vector<Poin> points(
(std::istream_iterator<Poin>(std::cin)),
std::istream_iterator<Poin>());
The other obvious problem you'd run into would be the use of the lambda expression:
[&](Poin const &p) { return p.in_rect(TL, BR); }
This can be worked around as well, but if you have trouble with either, I'd advise updating your compiler rather than munging the code. These were introduced in C++11, and (many) compilers supported them even before the standard was finalized. To reverse the old advertising slogan, this is a place it's better to switch than fight.
Upvotes: 8
Reputation: 15872
When coming from Java, you must break yourself of the bad habit of declaring all variables with the new
keyword. In C++, most of the time you will not use that keyword.
Poin TopLeft, BottomRight;
...
TopLeft = new Poin(x_top, y_top); // TopLeft of is type Poin, new returns a type Poin*
BottomRight = new Poin(x_bot, y_bot); // same here
What you want is really:
cin>>x_top;
cin>>y_top;
cin>>x_bot;
cin>>y_bot;
Poin TopLeft(x_top, y_top);
Poin BottomRight(x_bot, y_bot);
Upvotes: 1
Reputation: 2122
If you have a particular reason to use new
Poin* TopLeft;
Poin* BottomRight;
TopLeft = new Poin(x_top, y_top);
BottomRight = new Poin(x_bot, y_bot);
otherwise
Poin TopLeft(x_top, y_top);
Poin BottomRight(x_bot, y_bot);
If you're coming from a java background, and don't understand how c++ pointers work, then the second option would be far better for you!
Upvotes: 2
Reputation: 409166
In C++ you don't need to use new
to create new objects, just declaring the variable is enough:
Poin TopLeft, BottomRight;
There you go, two objects declared, defined and created.
If you want to specify constructor arguments, you can do that in the declaration:
Poin TopLeft(x_top, y_top), BottomRight(x_bot, y_bot);
You don't need new
until you start to learn about pointers, which you probably should do quite soon if you want to write any serious program. Also remember that in C++ dynamically allocated objects (that you allocate with new
) are not automatically released, you have to do that manually release them with delete
when done with the objects.
Upvotes: 4