0

In C++ by FLTK, to define a circle we use some code like this:

Circle c(Point(x,y), r);

And we can using vector_ref put and save them in a vector, like:

Vector_ref<Circle> vc;
vc.push_back(new Circle(Point(x,y),r));

OK, those were about Circle and no problem till now! Triangle can be defined like this for using in codes:

Graph_lib::polygon poly;
poly.add(Point(x1,y1),r1);
poly.add(Point(x2,y2),r2);
poly.add(Point(x3,y3),r3);

and this is a vector to saving them:

Vector_ref<Graph_lib::Polygon> vp;

The problem is that how to save/put triangles/polygons into that vp vector using new keyword like the circle does?

The code I used as an answer to the exercise no 12 (of here) is this:

/* The binary-tree class, one of the topics that has been said in Programming Principles and Practice using C++ book by Biarne Stroustrup.
   This code is written by R Abbasi (s.rabbasi@yahoo.com) */
#include <Simple_window.h>
#include <iostream>

vector <Graph_lib::Polygon> vpo;
vector <Point> vp;
int pow(int);

class Binary_tree: public Shape {
public:
    Binary_tree(Point _p, int l):level(l), p(_p) {  
        preparing(); }

    void preparing();
    void put_nodes(Point);
    void wheel(Point);
    void make_nodes(Point);
    void draw_lines() const {
        for(int i = 0; i*2+2 < vp.size(); i++) {
            fl_line(vp[i].x,vp[i].y,  vp[i*2+1].x,vp[i*2+1].y);
            fl_line(vp[i].x,vp[i].y,  vp[i*2+2].x,vp[i*2+2].y);
        }
    }

private:
    Point p;
    int i, j, k, level;
    double scale;
};
//**********************************

void Binary_tree::preparing() {
    if(level < 1) error("Bad inputted level!");
    else if (level == 1) put_nodes(p);
    else {
        scale = 5 * pow(level); 
        i = 1; j = 1; k = 3; 
        put_nodes(p); 
        make_nodes(p);
    }
}

//***************************************

void Binary_tree::put_nodes(Point p) { 
    vp.push_back(p);
    Graph_lib::Polygon poly;
    poly.add(Point(p.x-2,p.y));
    poly.add(Point(p.x,p.y-3));
    poly.add(Point(p.x+3,p.y));

    vpo.push_back(&poly);
}

//******************************************

void Binary_tree::wheel(Point p) {
    put_nodes(Point(p.x - scale, p.y+30));
    put_nodes(Point(p.x + scale, p.y+30));
}

//*****************************************

void Binary_tree::make_nodes(Point p) {
    while(vp.size() < (pow(k)-1))
        wheel(vp[vp.size()-i++]);

    if(i < pow(level)) {
        k++;
        scale *= 1.0/2.0;
        make_nodes(vp[vp.size()-i]);
    }
}

//*********************

int pow(int l)  {
    int m = 2; 
    for(int k = 2; k < l; k++) m *= 2; 
    return m;
}

//***************************************

int main() try
{
    Simple_window win(Point(),1300,500, "Binary_tree");
    int level;
    cout<< "Please enter the level of the Binary-tree:";
    if(!(cin>>level)) error("Bad number of level!");

    Point p(10*pow(level),20);
    Binary_tree b_t(p,level);

    vpo[0].set_color(Color::red);
    vpo[0].set_style(Line_style(Line_style::solid,3));
        win.attach(vpo[0]);
    for(int i=1; i<vpo.size(); i++) {
        vpo[i].set_color(Color::blue);
        win.attach(vpo[i]);
    }
    win.attach(b_t);
    win.wait_for_button();
    return 0;
}

//*****************************

catch(exception& e) {
    cerr << e.what() << "\n\a";
    return 0;
}

And errors are:

*Error 9 error C2664: 'void std::vector<_Ty>::push_back(Graph_lib::Polygon &&)' : cannot convert parameter 1 from 'Graph_lib::Polygon *' to 'Graph_lib::Polygon &&' c:\users\cs\documents\visual studio 2012\projects\test_1\test_1\test_1.cpp 53

14 IntelliSense: no instance of overloaded function "std::vector<_Ty, _Alloc>::push_back [with _Ty=Graph_lib::Polygon, _Alloc=std::allocator]" matches the argument list argument types are: (Graph_lib::Polygon ) object type is: std::vector> c:\Users\CS\Documents\Visual Studio 2012\Projects\test_1\test_1\test_1.cpp 53

Aria
  • 97
  • 1
  • 8
  • 1
    Do you really need to use `new`? If you do, you should say why. And explain how pushing a `Circle` pointer into a vector of `Circles` works. – juanchopanza Oct 11 '14 at 07:29
  • I guess you should draw your class inheritance. – Maxim Gotovchits Oct 11 '14 at 07:49
  • You will get a syntax error if you use new. Just use vc.push_back(Circle(Point(x,y),r)) - Have a look at your poly example - you don't use new there. – cup Oct 11 '14 at 11:16
  • 1
    C++ makes the distinction between pointers, references, local objects and temporary objects. You have to use the right form. When a function expects a dynamically-allocated object (i.e. a pointer), then use the `new` keyword. Otherwise, you must pass in a temporary object without the `new` keyword, and a copy of that object will be made by the function. This description is a simplification - you should have an introductory C++ book with you during the first 6 months of learning C++. – rwong Oct 11 '14 at 13:02
  • @cup: Using _vc.push_back(new Circle(Point(x,y),r));_ (in above code) doesn't make any error while the _vc.push_back(Circle(Point(x,y),r));_ makes _Debug Assertion failed_ error. So I need to use of new. Anyway, my problem is not circle, it's polygon. I need a way to push polygons into the vector or vector_ref. – Aria Oct 11 '14 at 13:22
  • @rwong: I'm reading [this](http://www.stroustrup.com/programming1.html) book and the exercise related to my problem is no 12 of [this](http://books.google.com/books?id=We21AwAAQBAJ&lpg=PP1&dq=programming%20principle%20and%20practice&pg=PA517#v=onepage&q&f=true). – Aria Oct 11 '14 at 13:26

1 Answers1

2

For Vector_ref<polygon> (using new)

From what I understand of Vector_ref, this is simply a std::vector with pointers and code to clean up the dynamically allocated memory at the end. This means you must use new to allocate your polygon. So, if you must use new, you can create your polygon first (using new) and then push it:

// Create your new polygon
polygon* poly = new polygon;
poly->add(Point(...));
poly->add(...);
poly->add(...);

// Push that polygon into the vector
vp.push_back(poly);

For std::vector<polygon*> (taking the address)

If the polygon doesn't go out of scope (i.e. you don't leave the function or pass a }) you can take the address of the polygon:

// Create polygon
polygon poly;
poly.add(...); // by 3

// Add the polygon to the vector
vp.push_back(&poly);

For std::vector<polygon> (making a copy)

If the vector is not an array of pointers, which is the case for std::vector<polygon> (but not for std::vector<polygon*> or Vector_ref<polygon>), then you should not use new or &. Instead if you just use push_back of the vector with the polygon, the polygon will be copied into the vector.

// Create your new polygon
polygon poly;
poly.add(...); // by 3

// Copy the polygon into the vector
vp.push_back(poly);
ilent2
  • 5,171
  • 3
  • 21
  • 30
  • Thank you for the answer. It's a simple and correct one. But since I haven't learned pointers until that part of the book (I offered its link above) I can't use of pointers and should by some other way solve the problem :( – Aria Oct 11 '14 at 13:49
  • Whenever you use the `new` keyword you are using a pointer. In this case I have assigned the pointer to a variable (denoted by the `*`). The only other difference is accessing members of pointers, instead of the `.` you can use `->`. – ilent2 Oct 11 '14 at 13:55
  • @user3724662 I have added an alternative, this still uses a pointer but hides it (mostly). Your original circle example used a pointer too, since it used the `new` keyword. – ilent2 Oct 11 '14 at 14:00
  • I used the second method and added he whole code into the question body. There are errors. Please look at the question once again. – Aria Oct 11 '14 at 14:17
  • @user3724662 Ah, I see. I assumed you were using `Vector_ref` for your polygons, not `std::vector`. As far as I can tell `Vector_ref` is an array of pointers with some clean up code. For your case you should be able to just use `push_back` with no fancy extras. If that doesn't work, post your new compiler output. Good luck. – ilent2 Oct 12 '14 at 13:09
  • Instead of `vector_ref` of polygons which would make many complexity I used a `vector_ref` of `Lines` which is a kind of `Shape` as well and is just like `Circle` (for putting into the `vector_ref`). Triangle is made of 3 lines so using `Lines` I could solve the problem. Thanks :) – Aria Oct 12 '14 at 15:00