|
If you have an object like this:
class Thing1 {
public:
Thing1 ();
} You can use it in another object:
class Composite {
public:
Composite ();
private:
Thing1* part;
};
Composite::Composite()
: part (new Thing1)
{
} In Composite , the member part is a pointer to a Thing1 . When a composite is constructed, first the program allocates on heap a new object of type Thing1 and invokes it constructor. Because constructor for Thing1 does not have any parameters there is no need for a list of parameters.
Next step:
You have another type of object Thing2 declared like:
class Thing2 {
public:
Thing2 (int param=42);
}; and the Composite object has 2 members:
class Composite {
public:
Composite ();
private:
Thing1* part;
Thing2* other_part;
}; The constructor of Composite could be:
Composite::Composite ()
: part (new Thing1) , other_part (new Thing2) {} because now the constructor for Thing1 needs a parameter but the parameter has a default value and the compiler will call the constructor with said value. Obviously, if you need a different value for the parameter, you will have to add it:
Composite::Composite ()
: part (new Thing1) , other_part (new Thing2(24) {}
Going back to the original question (which you seem to have deleted)
What you want to have is it something like:
class Composite{
public:
Composite ();
private:
Thing1 *part;
Thing1 *other_part;
{} ? Try to rephrase your question it terms of simple objects to make it easier for us to understand.
Mircea
|
|
|
|
|
Lets break this down:
1) The expression new Object creates a new instance of Object on the heap, and provides a pointer to the new object.
2) The expression foo( something ) makes a function call. We might be able to deduce that m_status() is a member function to some object, both from your descriptions elsewhere and the use of the m_ decoration, but that's not necessarily the case. It could be you are using m_ as a decoration for a menu object or a motorhome object or some other mystery object....
Together we have f(new Object) which (1) constructs a new Object on the heap, and then (2) calls a function f with a pointer to the newly constructed Object . What we don't know is if Object has a default constructor. It might not, in which case, as you observe over in the lounge, you must use f(new Object(param, ...) . There may be multiple constructors, so you'll need to check the documentation for the Object to see which one is most appropriate.
If you create an object with new , at some point delete Object should to be used to recover the allocated memory1. It's seems unlikely the the called function would do that, as it cannot know whether the pointer to Object is a pointer to a stack or heap object. Trying to delete a stack object is almost certainly going to cause Bad Things™ to happen. Maybe an immediate abort, maybe an exception gets thrown or maybe just a silent mess up of your data, with no indication that bad things have happened until some time later in the program. So you're probably better off to not use new Object as a parameter to a function. In general you should prefer a smart pointer ( Dynamic memory management - cppreference.com ) to new/delete in new development. But maybe the function does expect its parameter to be newly constructed within the parameter list and will delete before it returns? We don't know.
Footnotes:
1 This isn't strictly true. If you only create one instance of an object, the memory will be recovered when the program exits. A number of GNU C stdlib routines do this, allocating a block of memory when first called and re-using it as needed. The allocated memory is only "lost" to the executing program - assuming virtual memory and one of the usual operating systems (e.g. window, linux, macos, etc). That might not be true for some specialized use operating systems or for "stand-alone" programming environments.
"A little song, a little dance, a little seltzer down your pants"
Chuckles the clown
|
|
|
|
|
Thank you, that is exactly what I was asking about.
Plain explanation,,,,
I need to digest the "pointer to the object ".
My program just broke big time , so I am busy trying find where...
I have backup , but not up - to date...
Thanks again...
PS
I need to stay away from lounge, those folks are in their own world ,,,
definitely not same as mine
|
|
|
|
|
Salvatore Terress wrote: I need to digest the "pointer to the object ".
That's worrisome. That's basic C/C++ stuff. Something any programmer with more than a few weeks experience should at least have some familiarity with. You should also understand the relationship between a pointer and a reference.
Salvatore Terress wrote: My program just broke big time , so I am busy trying find where...
I have backup , but not up - to date..
Get yourself hooked up with a version control system like Git or SVN. There are public servers for both. If you need to keep you code proprietary (or just don't wish to share), either can be set up locally. If you need a local SVN/Git server, that might be a great project for a PI. If you're using QDevelop, then a quick google suggests that it supports several Version Control systems. Even if you're the only developer, being able to review and/or revert can save you a whole bunch of time. And red faces.
"A little song, a little dance, a little seltzer down your pants"
Chuckles the clown
|
|
|
|
|
Sorry, bu I need more explanations /help .
Here is my class constructor
SettingsDialog::SettingsDialog(QWidget *parent) :
QDialog(parent),
m_ui(new Ui::SettingsDialog),
m_status(new QLabel),
m_TAB_Connect(new A_BT_TAB_DIALOG),
m_intValidator(new QIntValidator(0, 4000000, this))
{
here is a snippet of class definition
A_BT_TAB_DIALOG *m_TAB_Connect = nullptr;
you said that
new A_BT_TAB_DIALOG),
builds a pointer - to object A_BT_TAB_DIALOG
and
m_TAB_Connect(new A_BT_TAB_DIALOG),
is a function call of function
m_TAB_Connect
that is not what I thought is happening
and I hope it is not some kind of Qt "stuff"
I am reading
m_TAB_Connect(new A_BT_TAB_DIALOG),
as
passing pointer m_TAB_Connect of (new) object A_BT_TAB_DIALOG
am I wrong?
I am not trying to nitpick, but I am having an issue accessing correct instance of
the parent class AND NEED to get this terminology correct.
|
|
|
|
|
Let's try and look at this set of parameters line by line
1. Why are you calling QDialog here? That line of code creates a new QDialog object, but you do not save any pointer to it, so what is the reason for that?
QDialog(parent),
2. I assume that m_ui is declared as a pointer to a Ui::SettingsDialog which you will refer to somewhere later.
m_ui(new Ui::SettingsDialog),
3. As with point 2 you create a new object whose pointer you store in m_status .
m_status(new QLabel),
4. Possibly the same as 2 and 3 but I have no idea what m_TAB_Connect is. Is it a pointer, or a method?
m_TAB_Connect(new A_BT_TAB_DIALOG),
5. Same as comment 4.
m_intValidator(new QIntValidator(0, 4000000, this))
So without further details of the class it is impossible to say whether this is correct or not. Constructors really should do the minimal initialisation necessary to create the object, that is just setting properties that do not require callouts to other classes. Any calls to other constructors, methods, API functions etc. is generally best left to an initialisation method.
|
|
|
|
|
If I understand your question correctly.
Constructors will (try to) construct derived objects before itself
ie. the base object needs to be constructed to be able to construct the derived classes.
class Base {};
class Child : public Base{}
Base will be constructed before Child.
CI/CD = Continuous Impediment/Continuous Despair
|
|
|
|
|
Correct - that is why I used term "nested objects ".
My goal is to have an application with logical , intuitive GUI . hence I have sort of main parent GUI object with children.
I am using " cut and paste " example which is "pop=up" dialog based , and I have added another windowing part to it.
Unfortunately I did not keep better track of these , basically TWO parallel methods.
And that what caused the problem.
With so much help received I am sure I can adjust my code to avoid further disasters..
and I do appreciate the help, very much.
|
|
|
|
|
This is a reply to your question in the Lounge, which as you well know is not the place for programming questions.
Salvatore Terress wrote: where to find decent description of the
this syntax
m_status(new QLabel),
It is part of the constructor for a MainWindow_Bluetooth object. And since that line follows the set of initializers, it means create a new QLabel object, and store its pointer in the variable m_status . Why you are doing that, only you can answer.
Bottom line, study the documentation for C++ classes, where all the syntax is explained.
|
|
|
|
|
Greetings Kind Regards
Please consider the C++ code below. It is utilized it to generate a locale formatted number e.g. "1,234". However subsequent I wish again to generate a number but not so formatted e.g. "1234". So I inquire can an imbued locale be removed from an output stream so no such locale specific formatting occurs. Of course another stream which has not been so imbued can be utilized for this purpose but prefer not to do so as such seems a less elegant solution.
Thank You Kindly
basic_ostringstream<char> _ostream;
_ostream.imbue(locale("en-US"));
_ostream << 1234;
|
|
|
|
|
_ostream.imbue(std::locale::classic());
If you want to be standard abiding, names prefixed with "_" are reserved in global namespace.
I can hear "man, is this guy pedantic!"
Mircea
|
|
|
|
|
May I please inquire how you would name the variable. It is my custom to utilize prefix '_' for identifiers of objects of standard template library types for brief simple functions as the purpose of such object is obvious in such situations instead of a lengthy explanatory name which I reserve for more lengthy more complicated functions.
|
|
|
|
|
It's a question of taste: put the underscore at the other end (ostream_ ), or come up with a different name (ostrm ). As in any question of taste, there isn't any right answer; my personal preference goes for trailing underscore.
The rule about leading underscore is not my invention. See C++ Language standard section 17.6.4.3.2 - Global names (page 429).
Mircea
|
|
|
|
|
I am seriously trying to learn more about C++_.
I did add a new class to the constructor, just following an examples , and
I do not understand why I am getting this error.
My own add is duplicate of existing , working class,
and I do no see why
it does no like the pointer.
m_serial(new QSerialPort(this),
m_TAB_Ext(new A_BT_TAB_DIALOG_EXT)
/mnt/A_BT_DEC10/A_APR13_APR15/A_APR9_MAR7_MAR19_CLEAN/A_BT_LIBRARY/terminal_Bluetooth/mainwindow_Bluetooth_copy.cpp:3088: error: called object type 'A_BT_TAB_DIALOG_EXT *' is not a function or function pointer
mainwindow_Bluetooth_copy.cpp:3088:22: error: called object type 'A_BT_TAB_DIALOG_EXT *' is not a function or function pointer
m_TAB_Ext(new A_BT_TAB_DIALOG_EXT())
~~~~~~~~~^
here is my class declaration
namespace Ui {
class A_BT_TAB_DIALOG_EXT;
class QMdiArea;
}
class A_BT_TAB_DIALOG_EXT : public QWidget
{
Q_OBJECT
public:
explicit A_BT_TAB_DIALOG_EXT(QWidget *parent = nullptr);
~A_BT_TAB_DIALOG_EXT();
private:
Ui::A_BT_TAB_DIALOG_EXT *ui;
QLabel *m_status = nullptr;
QMdiArea *m_mdiarea = nullptr;
QSerialPort *m_serial = nullptr;
};
|
|
|
|
|
There is a slight discrepancy in your code. You wrote:
m_serial(new QSerialPort(this),
m_TAB_Ext(new A_BT_TAB_DIALOG_EXT)
Meanwhile the compiler error message is:
m_TAB_Ext(new A_BT_TAB_DIALOG_EXT()) (note the extra pair of parenthesis).
The code you posted is potentially correct, assuming m_TAB_Ext is declared as:
A_BT_TAB_DIALOG_EXT *m_TAB_Ext; However the compiler error message seems to indicate that you have those extra parenthesis and, in this case, the compiler interprets it as a function call.
Mircea
|
|
|
|
|
Good catch, but even after removing the () I get same error.
m_serial(new QSerialPort(this),
m_TAB_Ext(new A_BT_TAB_DIALOG_EXT)
|
|
|
|
|
Not sure I understand what you try to do. Maybe the code samle is a bit too short. Where is the `m_TAB_ext` initialization line? I don;t see a declaration for `m_TAB_ext`.
Mircea
|
|
|
|
|
Quote: m_serial(new QSerialPort(this),
// sequence 1` st add HERE
m_TAB_Ext(new A_BT_TAB_DIALOG_EXT)
Which of the overloaded constructors of the QSerialPort class are you trying to call?
Could you please show full details of m_TAB_Ext variable?
"In testa che avete, Signor di Ceprano?"
-- Rigoletto
|
|
|
|
|
SOLVED
THANKS,
you have a very nice , positive , constructive way to lead to solution.
|
|
|
|
|
What is the definition of m_TAB_Ext ? It looks like it, or m_serial , is looking for a function reference/pointer, but you are passing it a pointer to a A_BT_TAB_DIALOG_EXT object.
|
|
|
|
|
May I please inquire what is a Q_OBJECT .
|
|
|
|
|
Here are all parameters definitions (?)
PS
There are no other errors / issues .
So what is
QSerialPort *m_serial = nullptr;
contributing to the issue / error and why is it part of the discussion?
( just asking )
<pre> private:
public:
A_BT_TAB_DIALOG_EXT *m_TAB_Ext = nullptr;
private:
void showStatusMessage(const QString &message);
Ui::MainWindow_Bluetooth *m_ui = nullptr;
QMdiArea *m_mdiarea = nullptr;
QLabel *m_status = nullptr;
Console *m_console = nullptr;
SettingsDialog *m_settings = nullptr;
QSerialPort *m_serial = nullptr;
SettingsDialog_RFcomm *m_settings_RFcomm = nullptr;
|
|
|
|
|
I inquire re/ Q_OBJECT because I do not understand why the compiler does not report an error re/ its usage in the code as written as I assume it is either the name of a type perhaps a class type or an identifier of an object of some type. In either case it would of course be a syntax error exempli gratia as per below:
class cfoo
{
int
public:
void foo();
} Likewise it is a syntax error to write the identifier of an object without a type specifier exempli gratia as per below:
class cfoo
{
xyz
public:
void foo();
} Perhaps Q_OBJECT is a macro hiding these details.
In conclusion I do not see the answer to my inquiry.
|
|
|
|
|
Sorry , I got sidetracked fixing the issue.
I have been told , not just advised, NOT to post Qt questions.
Since I am not welcomed
to do so I , on my own, do not want to discuss Qt here.
I think that is fair.
Cheers
|
|
|
|
|
I am using makefile / make DEFINES as common resource for project.
DEFINES += define PORT_CONFIGURATION
DEFINES += undefine SERIAL_SETUP
DEFINES += define STATUS_BAR
DEFINES += define TRACE_MENU
DEFINES += define TEST_SERIAL_PORT
DEFINES += define SERIAL_PORT_SETUP
DEFINES
# add Apr15
DEFINES += define DEBUG_MDI
DEFINES += define TRACE_CONSOLE
Is there a simple way to ERASE all DEFINES and start fresh?
My code has few places of DEFINES and commenting them out is impractical.
I did ask Mr Google , and the above did not work.
Thanks
.
|
|
|
|
|