Pages: 1 [2]   Go Down
Author Topic: Maybe a simple C++ Question [crosspost]  (Read 1531 times)
0 Members and 1 Guest are viewing this topic.
Norway@Oslo
Offline Offline
Edison Member
*
Karma: 12
Posts: 2033
loveArduino(true);
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
how to I create a private instance of another object within a class so that it gets constructed when the main class gets constructed

Here:
Code:
class A {
public:
      A(int param) {}
};

class B {
public:
      B(int param) : a(param) {}
private:
      A a;
};

void setup() {
      B b(3);
}

void loop() {}
smiley
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 14
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok.  Now what if the parameters for 'a' had nothing to do with the parameters for b?

Code:
class A {
public:
      A(int param) {}
};

class B {
public:
      B(int param) : a([glow]_As_arg[/glow])
                { [glow]complexLogicThatCalculates_As_arg[/glow] }
private:
      [glow]int _As_arg;[/glow]
      A a;
};

void setup() {
      B b(3);
}

void loop() {}

and to expand on my question... what if there is an array of As?

Code:
class A {
public:
      A(int param) {}
};

class B {
public:
      B(int param) : a(param) {}  [glow]// ???[/glow]
private:
      [glow]A arrOfA[10];[/glow]
};

void setup() {
      B b(3);
}

void loop() {}

or if there is another class "C"

Code:
class A {
public:
      A(int param) {}
};

[glow]class C {
public:
      C(int p1, int p2, int p3) {}
};[/glow]

class B {
public:
      B(int param) : a(param) {}  [glow]// ???[/glow]
private:
      A a;
      [glow]C c;[/glow]
};

void setup() {
      B b(3);
}

void loop() {}


Sorry if I seem slow about this, but I cannot seem to find any resources that will show me, in general, how the syntax works for this language.  :-[
Logged

Norway@Oslo
Offline Offline
Edison Member
*
Karma: 12
Posts: 2033
loveArduino(true);
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Are you sure you need to use libraries? [if not, let us know smiley]

Are you going to have many 'roads'? [if not, let us know smiley]

[if both answers was 'yes' read:]
If you want to use arrays, you need an empty constructor, and a construct/begin function for deferred construction of the library. This is often called two-phase construction.
« Last Edit: January 26, 2010, 02:04:00 pm by AlphaBeta » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 14
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I guess you guys are hammering home the "Don't Do That" point.

That's a good link, and is good reference for me.  Even IF I wanted to do that, I still don't have the syntax right to use the 'new' operator in the context of my project (which I guess I wanted to know all along, but as you guys have said "Don't Do That").


Maybe it's time to audit a C++ class at the community college.
Logged

Norway@Oslo
Offline Offline
Edison Member
*
Karma: 12
Posts: 2033
loveArduino(true);
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I thought the parts of your code that had the new operator had it because it was a bi product of what you tried to do.
If your question was about the new operator, you could've asked about it smiley-wink
And, I do not mean that as abrupt as it looks.


There is no implementation of the new operator in Arduinoworld
A google search on arduino + new + operator should give you some leads on how to implement it yourself.


If I'm hammering a point I think it would have to be something like: "Don't do that like you want it, but like it should be done". And again, no pun intended smiley

/me apparently has trouble with formulating polite english sentences  :-[
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 14
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
If your question was about the new operator, you could've asked about it

I guess I should have been more specific, like more specific than posting it highlighted in every single one of my responses.  smiley-razz


Quote
There is no implementation of the new operator in Arduinoworld
A google search on arduino + new + operator should give you some leads on how to implement it yourself.

Quick search says that I can't do what I've been trying to do all along, because I don't control the object that I'm trying to create an instance of (at least not without work that I don't feel like doing).  To be more specific, AsyncLabs TWEEETrequest object does not implement operator new and operator delete, so I won't be able to instansiate it as part of my library... which I really don't need to do, but I'm pretty OCD about code heirarchy. smiley-wink

I think we are finally lining up the "like it should be done" with "like I want it" (which is not possible in Arduinoworld).  Which I thought would be the simple question from the first post.  ;D

Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 551
Posts: 46257
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Which I thought would be the simple question from the first post.

But we enjoyed the whole give-and-take required to tell you that you can't do that.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 14
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You guys at least deserve to see the output of my project...

http://twitter.com/KegMonitor


Enjoy.
Logged

Australia
Offline Offline
Jr. Member
**
Karma: 0
Posts: 99
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Now what if the parameters for 'a' had nothing to do with the parameters for b?

You need another class to initialise the parameters for A:

Code:
class A {
public:
      A(int param) { }
};

class InitA {
public:
      InitA(int &param) { param = complexLogicThatCalculates_As_arg }
};

class B {
public:
      B(int param) : InitA(_As_arg), a(_As_arg)
                { whatever initialisation B needs }
private:
      int _As_arg;
      A a;
};

void setup() {
      B b(3);
}

void loop() {}

Quote
what if there is an array of As?

No, C++ currently does not support member array initialisation. The following works for primitive types but not user-defined classes. You could probably do it with std::vector but the Arduino compiler library doesn't support the STL AFAIK.

Code:
class A {
public:
      A(int param) {}
};

class InitA {
public:
      InitA(int (&param)[10]) {
            param[0] = ...;
            param[1] = ...;
            param[2] = ...;
            ...
      }
};

class B {
public:
      B(int param) : InitA(arrOfint) {}
private:
      int arrOfint[10];
};

void setup() {
      B b(3);
}

void loop() {}

or maybe even like this:

Code:
class A {
public:
      A(int param) {}
};

class InitA {
public:
      InitA(int (&param)[10]) {
            param[0] = ...; // Calculate c-tor parameter here
            param[1] = ...;
            param[2] = ...;
            ...
      }
};

class B {
public:
      B(int param) : InitA(arrOfint),
            arrOfA[0](arrOfint[0]),
            arrOfA[1](arrOfint[1]),
            arrOfA[2](arrOfint[2]),
            arrOfA[3](arrOfint[3]),
            arrOfA[4](arrOfint[4]),
            arrOfA[5](arrOfint[5]),
            arrOfA[6](arrOfint[6]),
            arrOfA[7](arrOfint[7]),
            arrOfA[8](arrOfint[8]),
            arrOfA[9](arrOfint[9]) { init B}
private:
      int arrOfint[10]; // array of As c-tor parameters
      A arrOfA[10];
};

void setup() {
      B b(3);
}

void loop() {}


Quote
or if there is another class "C"

This one's easier, member initialisation is a list, combine with the above methods if required.

Code:
class A {
public:
      A(int param) {}
};

class InitC {
public:
      InitC(int &arg1, int &arg2, int &arg3) {
      arg1 = complexLogicThatCalculates_Cs_first_arg;
      arg2 = complexLogicThatCalculates_Cs_second_arg;
      arg3 = complexLogicThatCalculates_Cs_third_arg;
      }
};


class C {
public:
      C(int p1, int p2, int p3) {}
};

class B {
public:
      B(int param) : a(param), InitC(cp1, cp2, cp3), c(cp1, cp2, cp3) {}
private:
      A a;
      int cp1, cp2, cp3;
      C c;
};

void setup() {
      B b(3);
}

void loop() {}

The main gotcha to remember is that the members are initialised in order of declaration in the class, not the order that they appear in the initialisation list.

Search for "C++ member initialization list" or "C++ array member initialization" and you'll get the details of the language syntax required.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 14
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks crimony, that's good info, and probably exactly the info that I was asking for the first time around, and what the other guys were giving me, but I just could not get my mind around it.  Your first example is exactly what I needed to really understand what they other guys were getting at.

I was playing with my code a bit tonight, and I've been playing with ways of inheriting the TWEETrequest object, but nothing seems to be working.

Here is my same horrible example code, modified to exhibit the exact same behavior I am getting in my real code:

Code:
//--------------------------------------------------
// Class A Library Function - Not easily modified
//--------------------------------------------------
class A
{
 public:
  A( char* auth, void(*funcPtr)() );
  void submit();  

 private:
  void (*_submitFunc)();

};

A::A( char* auth, void(*funcPtr)() )
{
  Serial.print("Class A Constructed! ");
  Serial.println(auth);
  
  _submitFunc = funcPtr;
}

void A::submit()
{
  Serial.print("Submitted!");
  _submitFunc();
}


//--------------------------------------------------
// Class B - My class
//--------------------------------------------------                                    
class B : public A
{
 private:
   void _privateSubmitter();
  
 public:
   B( char* Authorization );

};

[glow]B::B( char* Authorization ) : A ( Authorization, _privateSubmitter )[/glow]
{
  Serial.print("Class B Constructed! ");
}

void B::_privateSubmitter()
{
  Serial.print(" B's private Submitter! ");
}  


//--------------------------------------------------
// Basics
//--------------------------------------------------
void Submitter()
{
  Serial.print(" In The General Submitter! ");
}

void setup(){Serial.begin(9600);}

void loop()
{
  A standaloneA( "1234", Submitter );
  standaloneA.submit();

  B myB("4567");
  myB.submit();

  Serial.println("tic ");
  delay(10000);  
}

I am getting this on build (at the line highlighted):

In constructor 'B::B(char*)':
error: no matching function for call to 'A::A(char*&, <unresolved overloaded function type>)' At global scope:


So I am not passing the function pointer properly... I feel like I should put a (void(*)())) or something to explicitly tell it what is being passed... remember, I can't change A, everything I can do must be limited to B.

Hopefully this will be a simple syntax question. smiley-wink
« Last Edit: January 27, 2010, 12:29:31 am by aressa » Logged

Australia
Offline Offline
Jr. Member
**
Karma: 0
Posts: 99
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Your problem here is that pointers to object member functions are not the same as pointers to ordinary (anonymous) functions. They look the same but they have an implicit this pointer in the signature, so that the runtime can figure out which actual objects function instance to call. The callback member function needs to be static (ie. one for the whole class, not one per object) to use the simple method.

Have a look at http://www.newty.de/fpt/callback.html.

Try this:

Code:
class B : public A
{
 private:
   static void _privateSubmitter();
  
 public:
   B( char* Authorization );

};

It compiles for me.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 14
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Fantastic.  Got it going.  Thanks...
Logged

Pages: 1 [2]   Go Up
Jump to: