Gtkmm: create a Gtk::ComboBox which lists Gtk::DrawingArea - c++

I am trying to create a Gtk::ComboBox listing Gtk::DrawingArea widgets. I have followed this tutorial. So far, here is a minimal working example (i.e. which can be used to reproduce the issue) with Gtkmm3:
#include <gtkmm.h>
class NewPlayerRow : public Gtk::ListBoxRow
{
public:
NewPlayerRow();
private:
// Model for the combobox row: a disc with the appropriate player color...
struct NewPlayerDiscColorComboRowModel : public Gtk::TreeModel::ColumnRecord
{
NewPlayerDiscColorComboRowModel()
{
add(m_discColorIcon);
}
Gtk::TreeModelColumn<Gtk::DrawingArea> m_discColorIcon;
};
NewPlayerDiscColorComboRowModel m_comboRowModel;
Glib::RefPtr<Gtk::ListStore> m_listStore;
Gtk::ComboBox m_comboBox;
};
NewPlayerRow::NewPlayerRow()
{
// First, create and register the TreeModel:
m_listStore = Gtk::ListStore::create(m_comboRowModel);
m_comboBox.set_model(m_listStore);
// Then, populate the TreeModel:
Gtk::TreeModel::Row row = *(m_listStore->append());
row[m_comboRowModel.m_discColorIcon] = Gtk::DrawingArea();
row = *(m_listStore->append());
row[m_comboRowModel.m_discColorIcon] = Gtk::DrawingArea();
// Add the model columns to the Combo:
m_comboBox.pack_start(m_comboRowModel.m_discColorIcon);
add(m_comboBox);
}
int main(int argc, char** argv)
{
Glib::RefPtr<Gtk::Application> app{Gtk::Application::create(argc, argv, "com.github.bobmorane22.connectx")};
NewPlayerRow np;
Gtk::Window w;
w.add(np);
w.show_all();
return app->run(w);
}
When I compile this, I get the following error:
In file included from /usr/include/glibmm-2.4/glibmm/value.h:196:0,
from /usr/include/glibmm-2.4/glibmm/propertyproxy_base.h:25,
from /usr/include/glibmm-2.4/glibmm/propertyproxy.h:25,
from /usr/include/glibmm-2.4/glibmm/objectbase.h:24,
from /usr/include/glibmm-2.4/glibmm/object.h:29,
from /usr/include/pangomm-1.4/pangomm/context.h:32,
from /usr/include/gtkmm-3.0/gtkmm/widget.h:32,
from /usr/include/gtkmm-3.0/gtkmm/actiongroup.h:29,
from /usr/include/gtkmm-3.0/gtkmm/application.h:32,
from src/main.cpp:32:
/usr/include/glibmm-2.4/glibmm/value_custom.h: In instantiation of ‘static void Glib::Value<T>::value_copy_func(const GValue*, GValue*) [with T = Gtk::DrawingArea; GValue = _GValue]’:
/usr/include/glibmm-2.4/glibmm/value_custom.h:257:9: required from ‘static GType Glib::Value<T>::value_type() [with T = Gtk::DrawingArea; GType = long unsigned int]’
/usr/include/gtkmm-3.0/gtkmm/treemodelcolumn.h:134:64: required from ‘Gtk::TreeModelColumn<T>::TreeModelColumn() [with T = Gtk::DrawingArea]’
src/main.cpp:50:9: required from here
/usr/include/glibmm-2.4/glibmm/value_custom.h:283:33: error: use of deleted function ‘Gtk::DrawingArea::DrawingArea(const Gtk::DrawingArea&)’
dest_value->data[0].v_pointer = new(std::nothrow) T(source);
^
In file included from /home/morane/Programming/cpp/ConnectX/cxgui/include/GeometricShape.h:35:0,
from /home/morane/Programming/cpp/ConnectX/cxgui/include/Disc.h:35,
from src/../include/../include/CXDisc.h:35,
from src/../include/../include/GBDisc.h:37,
from src/../include/GameBoard.h:41,
from src/../include/GameWindow.h:17,
from src/main.cpp:34:
/usr/include/gtkmm-3.0/gtkmm/drawingarea.h:64:3: note: declared here
DrawingArea(const DrawingArea&) = delete;
which seems to indicate that the type in the combobox row model must be copyable for it to work. I have tried replacing the type Gtk::DrawingArea with std::string (which is copyable) in the above code and it builds fine and runs fine as well. I can see the combo box with its text rows.
Is there a way around this? I would really like to create a combo box which lists drawing areas.
EDIT Diving a little bit deeper in the error, I found that the issue is coming from the file value_custom.h in Glibmm. The following two functions seem to case the issue, since they try to access the copy member operation for the templated type (in my case Gtk::DrawingArea, which is not copyable, as mentionned above).
// static
template <class T>
GType Value<T>::value_type()
{
if(!custom_type_)
{
custom_type_ = Glib::custom_boxed_type_register(
typeid(CppType).name(),
&Value<T>::value_init_func,
&Value<T>::value_free_func,
&Value<T>::value_copy_func);
}
return custom_type_;
}
// static
template <class T>
void Value<T>::value_copy_func(const GValue* src_value, GValue* dest_value)
{
// Assume the source is not NULL. See value_init_func().
const T& source = *static_cast<T*>(src_value->data[0].v_pointer);
dest_value->data[0].v_pointer = new(std::nothrow) T(source);
}
I'm starting to feel like there is no way around this issue... The documentation for Glib::Value<T> even mentions that the type T has to implement copy assignment/construction.
If you have an idea, I'm all ears.

After more research, I have come to the conclusion that Gtk::ComboBoxes are simply not designed to hold widgets (hence Gtk::DrawingAreas) because is uses a Gtk::TreeModelColumn<T> in its TreeModel, where T needs to be copyable.
In other words, the types that compose your combobox model (ie. the types of what it actually lists when you click on it) must be copyable otherwise the framework won't let your code compile.
At first, the fact that widgets could not be copied made no sense to me, but after some research, I found this article, which clearly explains some of the (tough) issues that one might face when using copyable widgets.
In conclusion, it seems I am trying to accomplish something that would, in retrospective, be a bit weird UI-wise anyway and I will try to find some cleaner way to express my intent.

Related

auto type deduction coercion for templated class?

I have 2 issues in a template class I'm building. I've included example code below. First question is whether I can coerce the auto type deducted for a templated class. i.e.:
auto p = myvar;
where myvar is T<...>, could I force auto to detect Q<...>? This is simplified. Read on for a more clear explanation.
Edited for clarity: Let me explain what I'm doing. And I'd also like to indicate that this style code is working on a large-scale project perfectly well. I am trying to add some features and functions and in addition to smooth out some of the more awkward behaviors.
The code uses templates to perform work on n-dimensional arrays. The template has a top-level class, and a storage class underneath. Passing the storage class into the top level class allows for a top level class which inherits the storage class. So I start with NDimVar, and I have NDimStor. I end up with
NDimVar<NDimStor>
The class contains NO DATA except for the buffer of data:
class NDimStor<size_t... dimensions> {
int buffer[Size<dimensions...>()]
}
This makes the address of the class == the address of the buffer. This is key to the whole implementation. Is this an incorrect assumption? (I can see this works on my system without any issues, but perhaps this isn't always the case.)
When I create NDimVar<NDimStor<10,10>> I end up with a 10x10 array.
I have functions for getting pieces of the array, for example:
NDimVar<NDimStor<dimensions...>>::RemoveDim & get(int index);
This creates a new 1d array of 10 elements out of the 2d 10x10 array:
NDimVar<NdimStor<10>>
In order to return this as a reference, I use a reinterpret_cast at the location of the data I want. So in this example, get(3) would perform:
return reinterpret_cast<NDimVar≤NDimStor<dimensions...>>::RemoveDim&>(buffer[index * DimensionSumBelow<0>()]);
DimensionSumBelow<0> returns the sum of elements at dimensions 1+, i.e. 10. So &buffer[30] is the address of the referenced 1d NDimVar.
All of this works very well.
The only issue I have is that I would like to add on overlays. For example, be able to return a reference to a new class:
NDimVar<NDimPermute<NDimStor<10,10>,1,0>>
that points to the same original location along with a permutation behavior (swapping dimensions). This also works well. But I would like for:
auto p = myvar.Permute<1,0>()
to create a new copy of myvar with permuted data. This would work if I said:
NDimVar<NDimStor<10,10>> p = myvar.Permute<1,0>().
I feel that there is some auto type deduction stuff I could do in order to coerce the auto type returned, but I'm not sure. I haven't been able to figure it out.
Thanks again,
Nachum
What I want is:
1. Create temporary overlay classes on my storage, e.g. A_top<A_storage> can return a type called A_top<A_overlay<A_storage>> without creating a new object, it just returns a reference to this type. This changes the way the storage is accessed. The problem is upon a call to auto. I don't want this type to be instantiated directly. Can I modify the return to auto to be an original A_top?
#include <iostream>
using namespace std;
class A_storage {
public:
float arr[10];
A_storage () {
}
float & el (int index) {
return arr[index];
}
};
template <typename T> class A_overlay : T {
private:
A_overlay () {
cout << "A_overlay ()" << endl;
}
A_overlay (const A_overlay &) {
cout << "A_overlay (&)" << endl;
}
public:
using T::arr;
float & el (int index) {
return arr[10 - index];
}
};
template <typename T> class A_top;
template <typename T> class A_top : public T {
public:
A_top () {
}
A_top<A_overlay<A_storage>> & get () {
return reinterpret_cast<A_top<A_overlay<A_storage>>&>(*this);
}
};
using A = A_top<A_storage>;
int main (void) {
A a;
auto c = a.get(); // illegal - can i auto type deduce to A_top<A_storage>?
return 0;
}
If a function accepts (A_top<A_storage> &) as a parameter, how can I create a conversion function that can cast A_top<A_overlay<A_storage>>& to A_top<A_storage>& ?
Thanks,
Nachum
First, your design doesn't look right to me, and I'm not sure if the behaviour is actually well-defined or not. (Probably not.)
In any case, the problem is not with auto. The error is caused by the fact that the copy constructor of A_overlay is private, while you need it to copy A_top<A_overlay<A_storage>> returned by a.get() to auto c.
(Note that the auto in this case obviously gets deduced to A_top<A_overlay<A_storage>>, I assume you made a typo when said that it's A_top<A_storage>.)
Also note that A_storage in A_top::get() should be replaced with T, even if it doesn't change anything in your snippet because you only have T == A_storage.
If a function accepts (A_top &) as a parameter, how can I create a conversion function that can cast A_top> to A_top& ?
Ehm, isn't it just this:
return reinterpret_cast<A_top<A_storage>&>(obj);
reinterpret_cast should almost never be used. It essentially remove any compiler validation that the types are related. And doing unrelated cast is essentially undefined behavior as it essentially assume that derived classes are always at offset 0...
It does not make any sense to write such code. It is not maintainable and hard to understand what you are trying to achieve. It look like you want to pretend that your A_top<A_storage> object is a A_top<A_overlay<A_storage>> object instead. If this is what you want to do, then declare A alias as that type.
In your code, it look like you want to invert the indexing so that item at position 10 is returned when you ask item at position 0 and vice versa. Do you really think, that it is obvious from your obfuscated code? Never write such bad code.
Something like
class A_overlay {
public:
float & el (int index) { return arr[10 - index]; }
private:
A_storage arr;
};
would make much more sense than your current code.
No cast needed.
Easy to understand.
Well defined behavior.
You might keep your job.
And obviously, you would update the following line as appropriate:
using A = A_top<A_storage>;
Also, if A_top has no useful purpose, then why not using A_overlay directly? And why are you using template if A_storage is not a template? Do you really want to reuse such mess elsewhere in your code base.
Obviously, your code inheritance does not respect IS-A relationship if your write such code. So it is clearly a bad design!

Builder pattern: making sure the object is fully built

If for example I have a builder set up so I can create objects like so:
Node node = NodeBuilder()
.withName(someName)
.withDescription(someDesc)
.withData(someData)
.build();
How can I make sure that all variables used to build the object have been set before the build method?
Eg:
Node node = NodeBuilder()
.withName(someName)
.build();
Isn't a useful node because the description and data haven't been set.
The reason I'm using the builder pattern is because without it, I'd need a lot of combination of constructors. For example the name and description can be set by taking a Field object, and the data can be set using a filename:
Node node = NodeBuilder()
.withField(someField) //Sets name and description
.withData(someData) //or withFile(filename)
.build(); //can be built as all variables are set
Otherwise 4 constructors would be needed (Field, Data), (Field, Filename), (Name, Description, Data), (Name, Description, Filename). Which gets much worse when more parameters are needed.
The reason for these "convenience" methods, is because multiple nodes have to be built, so it saves a lot of repeated lines like:
Node(modelField.name, modelField.description, Data(modelFile)),
Node(dateField.name, dateField.description, Data(dateFile)),
//etc
But there are some cases when a node needs to be built with data that isn't from a file, and/or the name and description are not based on a field. Also there may be multiple nodes that share the same values, so instead of:
Node(modelField, modelFilename, AlignLeft),
Node(dateField, someData, AlignLeft),
//Node(..., AlignLeft) etc
You can have:
LeftNode = NodeBuilder().with(AlignLeft);
LeftNode.withField(modelField).withFile(modelFilename).build(),
LeftNode.withField(dateField).withData(someData).build()
So I think my needs match the builder pattern pretty well, except for the ability to build incomplete objects. The normal recommendation of "put required parameters in the constructor and have the builder methods for the optional parameters" doesn't apply here for the reasons above.
The actual question: How can I make sure all the parameters have been set before build is called at compile time? I'm using C++11.
(At runtime I can just set a flag bits for each parameter and assert that all the flags are set in build)
Alternatively is there some other pattern to deal with a large number of combinations of constructors?
Disclaimer: This is just a quick shot, but I hope it gets you an idea of what you need.
If you want this to be a compiler time error, the compiler needs to know about the currently set parameters at every stage of the construction. You can achieve this by having a distinct type for every combination of currently set parameters.
template <unsigned CurrentSet>
class NodeBuilderTemplate
This makes the set parameters a part of the NodeBuilder type; CurrentSet is used as a bit field. Now you need a bit for every available parameter:
enum
{
Description = (1 << 0),
Name = (1 << 1),
Value = (1 << 2)
};
You start with a NodeBuilder that has no parameters set:
typedef NodeBuilderTemplate<0> NodeBuilder;
And every setter has to return a new NodeBuilder with the respective bit added to the bitfield:
NodeBuilderTemplate<CurrentSet | BuildBits::Description> withDescription(std::string description)
{
NodeBuilderTemplate nextBuilder = *this;
nextBuilder.m_description = std::move(description);
return nextBuilder;
}
Now you can use a static_assert in your build function to make sure CurrentSet shows a valid combination of set parameters:
Node build()
{
static_assert(
((CurrentSet & (BuildBits::Description | BuildBits::Name)) == (BuildBits::Description | BuildBits::Name)) ||
(CurrentSet & BuildBits::Value),
"build is not allowed yet"
);
// build a node
}
This will trigger a compile time error whenever someone tries to call build() on a NodeBuilder that is missing some parameters.
Running example: http://coliru.stacked-crooked.com/a/8ea8eeb7c359afc5
I ended up using templates to return different types and only have the build method on the final type. However it does make copies every time you set a parameter:
(using the code from Horstling, but modified to how I did it)
template<int flags = 0>
class NodeBuilder {
template<int anyflags>
friend class NodeBuilder;
enum Flags {
Description,
Name,
Value,
TotalFlags
};
public:
template<int anyflags>
NodeBuilder(const NodeBuilder<anyflags>& cpy) : m_buildingNode(cpy.m_buildingNode) {};
template<int pos>
using NextBuilder = NodeBuilder<flags | (1 << pos)>;
//The && at the end is import so you can't do b.withDescription() where b is a lvalue.
NextBuilder<Description> withDescription( string desc ) && {
m_buildingNode.description = desc;
return *this;
}
//other with* functions etc...
//needed so that if you store an incomplete builder in a variable,
//you can easily create a copy of it. This isn't really a problem
//unless you have optional values
NodeBuilder<flags> operator()() & {
return NodeBuilder<flags>(*this);
}
//Implicit cast from node builder to node, but only when building is complete
operator typename std::conditional<flags == (1 << TotalFlags) - 1, Node, void>::type() {
return m_buildingNode;
}
private:
Node m_buildingNode;
};
So for example:
NodeBuilder BaseNodeBuilder = NodeBuilder().withDescription(" hello world");
Node n1 = BaseNodeBuilder().withName("Foo"); //won't compile
Node n2 = BaseNodeBuilder().withValue("Bar").withName("Bob"); //will compile
Disclaimer: this is an idea. I'm not sure it even works. Just sharing.
You might try to:
remove build() method from NodeBuilder
regroup your mandatory fields into a single builder method of NodeBuilder, say NodeBuilder::withFieldData(bla, bli, blu) and/or NodeBuilder::withFieldData(structBliBlaBLU).
make withFieldData() to return a builder of a different type, say NodeBuilderFinal. Only this type of builder has build() method. You may inherit non-mandatory methods from NodeBuilder. (Strictly speaking, NodeBuilderFinal is a "Proxy" object)
This will enforce user to call withFieldData() before build(), while allowing to call other builder methods in arbitrary order. Any attempt to call build() on non-final builder will trigger compiler error. build() method will not show up in autocompletion until final builder is made ;).
If you don't want monolithic withFieldData method, you may return different proxies from each "field" method, like NodeBuilderWithName, NodeBuilderWithFile, and from those, you can return NodeBuilderWithNameAndFile, etc. until final builder will be built. This is quite hairy and will require many classes to be introduced to cover different orders of "field" calls. Similarly to what #ClaasBontus proposed in comments, you can probably generalize and simplify this with templates.
In theory, you may try to enforce more sophisticated constraints by introducing more proxy objects into the chain.
The only way I can imagine would be to have a number of static builder methods (or constructors) one for each set of required parameters that would return a builder instance, and then simple instance methods to set (or overwrite) parameters and that return the instance.
It will allow compile time checking, but at the price of a much more complex API, so I strongly advise you not to use it unless you really have good reasons to do.
This question can not be outdated. Let me share my solution to this problem.
class Car; //object of this class should be constructed
struct CarParams{
protected:
std::string name_;
std::string model_;
int numWheels_;
int color_;
struct Setter_model;
struct Setter_numWheels;
struct Setter_color;
public:
class Builder;
};
struct CarBuilder : CarParams{ //starts the construction
Setter_model& set_name(const std::string& name){
name_ = name;
return reinterpret_cast<Setter_model&>(*this);
}
};
struct CarParams::Setter_model : CarParams{
Setter_numWheels& set_model(const std::string& model){
model_ = model;
return reinterpret_cast<Setter_numWheels&>(*this);
}
};
struct CarParams::Setter_numWheels : CarParams{
Setter_color& set_numWheels(int numWheels){
numWheels_ = numWheels;
return reinterpret_cast<Setter_color&>(*this);
}
};
struct CarParams::Setter_color : CarParams{
Builder& set_color(int color){
color_ = color;
return reinterpret_cast<Builder&>(*this);
}
};
class CarParams::Builder : CarParams{
private:
//private functions
public:
Car* build();
// optional parameters
};
The class Car is defined bellow:
class Car{
private:
std::string name_;
std::string model_;
int numWheels_;
int color_;
public:
friend class CarParams::Builder;
//other functions
};
And build function in .cpp:
Car* CarParams::Builder::build(){
Car* obj = new Car;
obj->name_ = std::move(name_);
obj->model_ = std::move(model_);
obj->numWheels_ = numWheels_;
obj->color_ = color_;
return obj;
}
Maybe it is a little bit complicated, but looks nice on client side:
std::string name = "Name";
std::string model = "Model";
Car* newCar = CarBuilder()
.set_name(name)
.set_model(model)
.set_numWheels(3)
.set_color(0x00ffffff)
.build();
The error will occur in compile-time, if you miss something before build(). One more disadvantage is the strict order of arguments.
It can be combined with optional parameters.

How do I differentiate between commonly named methods shared by two components of my class?

I have a class structure that looks something like this:
template <typename T>
class Origin
{
public:
void SetOrigin(T x, T y) { __x = x; __y = y; }
void SetOrigin(vector2<T> vect) { __x = vect.x; __y = vect.y; }
private:
T __x;
T __y;
}
class Sprite : Origin<float>
{
public:
using Origin::SetOrigin;
}
class Text : Origin<int>
{
public:
using Origin::SetOrigin;
}
class Button : Sprite, Text
{
public:
using Sprite::SetOrigin;
using Text::SetOrigin;
}
The class Button should have 2 different origins, the origin of the Text (where is the text in the Button) and the origin of the Button itself.
I don't want to have to cast the argument to float or int, because it should be obvious what method is called, so I'd like to call the second one btn.SetTextOrigin(x, y).
In this very simple case, I can just reimplement the methods with different names, but I have to make as many implementations as there are overloads of SetOrigin in class Sprite.
Is there an easier way to use all SetOrigin methods with a different name than to reimplement all of them? (Implementing 20 functions just to have a different name is pretty boring.)
For example, is it possible to change the name of a method in the derived class without rewriting each overloaded function? I think of something like:
using Text::SetOrigin as SetTextOrigin;
or
using SetTextOrigin = Text::SetOrigin
But I haven't found anything, if there is nothing like that, what would you suggest doing in that case?
Well, it looks to me that the button is better implemented as containing Sprite and Text. It won't save you anything on typing, in fact, you'll likely write a little bit more code, but it be a cleaner design. The button is neither a sprite or text - it can have a sprite and a text. So making the sprite and text member variables would be a lot more straightforward way of expressing the nature of their relationship.
Also, should the button have an origin different from either the sprite or text, e.g. say, the location of button's corner?
Are all buttons on the system expected to have both the text and the image?
Is it possible to add other elements to the button with the origin. I don't know, maybe two text elements with different fonts?
In this case, you may end up aggregating the origin elements.
I believe that you can call the functions like this
button myButton;
myButton.text::setOrigin();
myButton.sprite::setOrigin();
You could implement two different named methods:
class Button : public Sprite, public Text
{
public:
void SetSpriteOrigin()
{
Sprite::SetOrigin();
}
void SetTextOrigin()
{
Text::SetOrigin();
}
private:
void SetOrigin(); // Prevent users from using this ambiguous method.
};

Linking pointers to pointers between classes (communicating classes)

I've tried to solve my problem for 2 days now and failed miserably. Internet does not help.
What I'm trying to do is to communicate two classes which reside within another class.
This is my first "big" project so I assume my design is terrible for you guys.
Also, my program is split between a lot of files which may be confusing.
Lets hit it! For the sake readability, I've changed every member to public.
This is my MainOGLController class which is the main class that controls everything my program does:
class MainOGLController
{ // I deleted constructor/destructor from this quote
public:
DisplayController* Display;
StellarManager* Manager; // it will need to use something from Display
void RenderScene();
bool CreateNewDisplay(int, char*[]); // argc argv
}
Ok, this is how i create instance of this class in file with main():
#include "MainOGLController.h"
MainOGLController Controller;
int main(int argc, char* argv[])
{
if ( Controller.CreateNewDisplay(argc, argv) ) return 1; // if it fails then exit;
// some opengl code here
return 0;
}
Now you are probably wondering how does the CreateNewDisplay method look like:
bool MainOGLController::CreateNewDisplay(int argc, char* argv[])
{
Display = new DisplayController(argc, argv);
Manager = new StellarManager(&Display); // me trying to make reference to Display
// to be able to use it within Manager
//ogl code
else return 0;
}
OK, so I'm creating Manager there and now we should see how i created the StellarManager class:
class StellarManager
{
std::vector<Stellar*> VectorManager; // objects from this vector will need to use
// ptrDisplay to access Display
DisplayController* ptrDisplay;
StellarManager(DisplayController&);
void addEntity();
};
Now for the constructor:
StellarManager::StellarManager(DisplayController& _p) // me trying to do anything
{
*ptrDisplay = _p;
}
So at this point I should have instance of MainOGLController, and within it, a pointer to DisplayController and StellarController, where StellarController should have its own pointer to the same DisplayController.
Now somewhere withing working piece of code I'm calling the addEntity method:
void StellarManager::addEntity()
{
VectorManager.push_back(new Stellar(&ptrDisplay); // sending ptrDisplay so that the
// Stellar object can use it
}
Stellar class is defined like this:
class Stellar
{
public:
DisplayController* ptrDisplay;
Stellar(DisplayController**);
void Draw(); // finally, heres where i want to use this Display pointer
};
Stellar constructor:
Stellar::Stellar(DisplayController** _p)
{
*ptrDisplay = **_p;
}
OKAY! Thats the final piece. All i want to do now is simply call method Draw which belongs to Stellar class and use Display which is located in MainOGLController.
Manager->VectorManager[0].Draw();
Oh and the Draw looks just like this:
void Stellar::Draw(int _mode)
{
GLMatrixStack* mvm = &(ptrDisplay->modelViewMatrix);
mvm->Scale(2, 0.5, 0.5); // Scale is a method from GLMatrixStack
}
Thats all folks, if theres any better way of doing this, im all ears.
What I did does not work, I'm able to use the *ptrDisplay from Stellar class but nothing happens so I guess I'm not using its reference but a copy.
Sorry, I know this is a lot of code and it may be very confusing. I just dont know what to do now...
It looks like the problem is here:
Stellar::Stellar(DisplayController** _p)
{
*ptrDisplay = **_p;
}
You're dereferencing a pointer (ptrDisplay) that was never initialized. This results in undefined behavior. I think this captures what you wanted to do:
Stellar::Stellar(DisplayController* _p) : ptrDisplay(_p)
{
}
It's not necessary to pass a pointer-to-pointer-to-DisplayController; all your Stellar class needs is a pointer to a DisplayController. Moreover, it sounds like you don't want to dereference _p and copy it, so simply copying the pointer (via ptrDisplay(_p)) will result in ptrDisplay pointing to the same object as _p.

Passing this to an object within an object during the constructor call

I am trying to iron out my first compile in a long time, and I think this is the last hurdle.
I am trying to create this type of hierarchy in my design.
class chin_
{
private:
charon_* engine;
public:
chin_();
chin_(charon_ &handle)
{
engine = handle;
}
~chin_();
};
//////////////
class charon_ {
private:
chin_ engine_input;
public:
charon_(){
engine_input = chin_(this);
}
~charon_();
};
I am getting errors that tell me there is no matching function for call to
'chio::chin_::chin()'
it also says, mind you this is only when I change the constructor to charon_&
public:
chin_(const charon_ &handle)
{
engine = handle;
}
sys/../headers/chio.h:104:5: note: no known conversion for argument 1 from ‘charon::charon_* const’ to ‘const charon::charon_&’
When I use the * instead of & I get this instead, which is by far more baffling.
sys/../headers/chio.h:104:5: note: chio::chin_::chin_(const charon::charon_*)
sys/../headers/chio.h:104:5: note: candidate expects 1 argument, 0 provided
I've tried this and that, and I figure it is probably something super simple. I've tried to match my code up squarely with the examples I've found though so I don't know what else I should be trying, I'd like to be able to figure this sort of stuff out on my own. I just am not having any luck with it.
EDIT:
I update the code but I left the updated error for the bottom.
sys/chin.cpp:19:14: error: cannot convert ‘charon::charon_’ to ‘charon::charon_*’ in assignment
It takes me to this code
chin_::chin_(charon_ &handle) {
engine = handle;
}
engine is defined as
charon_* engine; and handle appears to be an address and should fall right into place, but it isn't. I think I am not using this correctly.
When you declare something like this :
chin_ engine_input;
chin_ needs a constructor with no parameters or you have to pass the parameters to it in the initializer list, otherwise you will get the error about no matching constructor.
What you can do is either have a default constructor that takes no params. Or make engine_input a pointer and create it with :
engine_input = new chin_(handle);
Alternatively you can pass handle to chin_ in the initializer list like this :
foo::foo(charon* handle):
chin_(handle)
{
}