Version: 1.1.1 (using KDE KDE 3.1.1) Installed from: RedHat RPMs Compiler: compiler unrelated OS: Linux There are several keywords missing for declaring functions (operations, methods, whatever) and variables in C++: virtual (only pure virtual declaration is possible as-is) const volatile register implicit explicit friend inline unsigned Check-boxes are a great way to choose these. ClassBuilder is a great example, and has many useful features you might want to consider using. It's another open-source UML proggy; it was originally written for win32 with mfc, though it is being ported to GNU/Linux. If you haven't seen it yet, it's worth taking a look at. Umbrello could be great if a lot of features from ClassBuilder are brought into it. Find it at: https://sourceforge.net/projects/classbuilder Homepage: http://members.lycos.nl/JimmyVenema/ClassBuilder/ClassBuilder.htm Also, more importantly (to me), it is not possible to create templated types. This is an extremely important feature to me, as I do lots of templated programming, and use templates to create policy-driven designs (not usable without templates). Oh, one more request: it would be great if you could use the katepart to allow the user to edit the body of an operation, and have it inserted at code generation time (great for getter/setter functions, and anything else small). Oops, just one more thing: comments for operations and attributes don't always get saved when you close the properties dialog. They don't seem to ever be saved when the comment in question is highlighted when the dialog is closed.
These are a bit language specific, the options currently available are all part of UML but most of these arn't recognised in UML. Maybe they could be part of Brian T's new code generator bits. Of course some are a bit obscure, I've no idea what half of them do.
virtual is for poly-morphism, as I'm sure you're all aware. const can be used more than one might realize: const Object * pointer; // points to const object Object * const pointer; // const pointer const Object * const pointer; // const pointer to const object volatile // C++'s recognition of threads; tells compiler not to cache // the volatile data type's value, to prevent thread A from // reading an obsolete value (the value it was before it was // changed by thread B, but hasn't yet been written back to // the cached area of memory yet). Keeps the value in physical // memory instead of caching it in a register register // for optimization; tells compiler this variable is to be used // often, keep it in a register. If overused, can actually // degrade performance, but if used thoughtfully, can help performance implicit // default for functions; opposite of explicit; rarely used explicit // tells the compiler that, say, a user defined type conversion // must be explicitly called upon: MyInt b; int a = MyInt( b ); // instead of int a = b; // implicit conversion form friend // allows a friend class to access its "friend's" classes members inline // optimization I'm sure you all know unsigned // again, obvious Just thought I'd fill you in on the blanks for whichever ones you didn't know. Thanks for assigning this.
Oh, I also forgot the keyword mutable. (In case anyone is not familiar with the keyword mutable, it's a flag to tell the compiler the constness of a variable can be cast away) Ex: class A { public: mutable int myint; int notmyint; }; int main( int argc, char** argv ) { const A myA; myA.myint = 5; // **** ERROR **** myint is const because it's containing // class is const const_cast<A>(myA).myint = 5; // This compiles fine because its constness // has been cast away by const_cast<T>() const_cast<A>(myA).notmyint = 5; // **** ERROR **** will not compile because // notmyint was not declared mutable } I think I've thought of all the neccessary missing keywords now (hopefully). BTW, http://www.gotw.ca/gotw/006.htm is a great guru article on when to use const and when to not, if anyone's interested in it. It's by Herb Sutter, good article.
> These are a bit language specific, the options currently available are all > part of UML but most of these arn't recognised in UML. > Maybe they could be part of Brian T's new code generator bits. I agree that the code generation could handle this, and I think the way to handle these is through stereotypes and expanded options at various points in the code generation interface (I seem to recall someone else expressing this viewpoint too). After KDE 3.2 release, this can be a priority for code generation development (and we will need to think carefully about how stereotypes will be implemented so they may be used in code generation...I wonder if there are any 'standard' stereotypes for various languages we can leverage??)
is there any activity on getting at least the "const" keyword to work???
> is there any activity on getting at least the "const" keyword to work??? Not to my knowledge. Feel free to submit patches.
*** Bug 116242 has been marked as a duplicate of this bug. ***
SVN commit 490686 by okellogg: Implement "const" for methods in the old and new C++ generators. Corresponds to the the XMI attribute "isQuery". CCBUG:60452 M +2 -0 codegenerators/cppheadercodeoperation.cpp M +8 -4 codegenerators/cppsourcecodeoperation.cpp M +3 -0 codegenerators/cppwriter.cpp M +10 -5 dialogs/umloperationdialog.cpp M +1 -0 dialogs/umloperationdialog.h M +15 -1 operation.cpp M +11 -0 operation.h --- branches/KDE/3.5/kdesdk/umbrello/umbrello/codegenerators/cppheadercodeoperation.cpp #490685:490686 @@ -149,6 +149,8 @@ // virtual functions start = (inlinePolicy ? " {" : ";"); end = (inlinePolicy ? "}" : ""); + if (pOp->getConst()) + prototype += " const"; if (interface || pOp->getAbstract()) { // constructor can't be virtual or abstract if (!pOp->isLifeOperation()) { --- branches/KDE/3.5/kdesdk/umbrello/umbrello/codegenerators/cppsourcecodeoperation.cpp #490685:490686 @@ -93,11 +93,15 @@ // if a property has a friend stereotype, the operation should // not be a class name - QString startText; + QString startText = returnType + " "; + if (!o->getStereotype().isEmpty() && o->getStereotype(false) == "friend") - startText = returnType + " " + methodName + " ("+paramStr+") {"; - else - startText = returnType + " " + className + "::" + methodName + " ("+paramStr+") {"; + startText += className + "::"; + startText += methodName + " ("+paramStr+")"; + if (o->getConst()) + startText += " const"; + startText += " {"; + setStartMethodText(startText); // Only write this out if its a child of an interface OR is abstract. --- branches/KDE/3.5/kdesdk/umbrello/umbrello/codegenerators/cppwriter.cpp #490685:490686 @@ -1196,6 +1196,9 @@ } str += " )"; + if (op->getConst()) + str += " const"; + // method body : only gets IF its not in a header if (isHeaderMethod && !INLINE_OPERATION_METHODS) str +=";"; // terminate now --- branches/KDE/3.5/kdesdk/umbrello/umbrello/dialogs/umloperationdialog.cpp #490685:490686 @@ -86,11 +86,14 @@ genLayout -> addWidget(m_pStereoTypeCB, 1, 1); m_pAbstractCB = new QCheckBox( i18n("&Abstract operation"), m_pGenGB ); - m_pAbstractCB -> setChecked( m_pOperation -> getAbstract() ); + m_pAbstractCB -> setChecked( m_pOperation->getAbstract() ); + genLayout -> addWidget( m_pAbstractCB, 2, 0 ); m_pStaticCB = new QCheckBox( i18n("Classifier &scope (\"static\")"), m_pGenGB ); - m_pStaticCB -> setChecked( m_pOperation -> getStatic() ); - genLayout -> addWidget( m_pAbstractCB, 2, 0 ); + m_pStaticCB -> setChecked( m_pOperation->getStatic() ); genLayout -> addWidget( m_pStaticCB, 2, 1 ); + m_pQueryCB = new QCheckBox( i18n("&Query (\"const\")"), m_pGenGB ); + m_pQueryCB -> setChecked( m_pOperation->getConst() ); + genLayout -> addWidget( m_pQueryCB, 2, 2 ); topLayout -> addWidget( m_pGenGB ); @@ -485,6 +488,8 @@ else m_pOperation->setTypeName(typeName); + m_pOperation->setStereotype( m_pStereoTypeCB->currentText() ); + bool isAbstract = m_pAbstractCB->isChecked(); m_pOperation -> setAbstract( isAbstract ); if (isAbstract) { @@ -495,8 +500,8 @@ */ classifier->setAbstract(true); } - m_pOperation -> setStatic( m_pStaticCB -> isChecked() ); - m_pOperation -> setStereotype( m_pStereoTypeCB->currentText() ); + m_pOperation->setStatic( m_pStaticCB->isChecked() ); + m_pOperation->setConst( m_pQueryCB->isChecked() ); return true; } --- branches/KDE/3.5/kdesdk/umbrello/umbrello/dialogs/umloperationdialog.h #490685:490686 @@ -99,6 +99,7 @@ QLineEdit * m_pNameLE; QCheckBox * m_pAbstractCB; QCheckBox * m_pStaticCB; + QCheckBox * m_pQueryCB; QPushButton* m_pDeleteButton; QPushButton* m_pPropertiesButton; KArrowButton* m_pUpButton; --- branches/KDE/3.5/kdesdk/umbrello/umbrello/operation.cpp #490685:490686 @@ -271,6 +271,14 @@ return (isConstructorOperation() || isDestructorOperation()); } +void UMLOperation::setConst(bool b) { + m_bConst = b; +} + +bool UMLOperation::getConst() const { + return m_bConst; +} + bool UMLOperation::showPropertiesDialogue(QWidget* parent) { UMLOperationDialog dialogue(parent, this); return dialogue.exec(); @@ -278,6 +286,7 @@ void UMLOperation::saveToXMI( QDomDocument & qDoc, QDomElement & qElement ) { QDomElement operationElement = UMLObject::save("UML:Operation", qDoc); + operationElement.setAttribute( "isQuery", m_bConst ? "true" : "false" ); QDomElement featureElement = qDoc.createElement( "UML:BehavioralFeature.parameter" ); if (m_pSecondary) { QDomElement retElement = qDoc.createElement("UML:Parameter"); @@ -287,7 +296,6 @@ retElement.setAttribute( "kind", "return" ); featureElement.appendChild( retElement ); } else { - //operationElement.setAttribute( "type", m_SecondaryId ); kdDebug() << "UMLOperation::saveToXMI: m_SecondaryId is " << m_SecondaryId << endl; } @@ -331,6 +339,12 @@ } } } + QString isQuery = element.attribute( "isQuery", "" ); + if (!isQuery.isEmpty()) { + // We need this extra test for isEmpty() because load() might have been + // called again by the processing for BehavioralFeature.parameter (see below) + m_bConst = (isQuery == "true"); + } QDomNode node = element.firstChild(); if (node.isComment()) node = node.nextSibling(); --- branches/KDE/3.5/kdesdk/umbrello/umbrello/operation.h #490685:490686 @@ -184,6 +184,16 @@ bool isLifeOperation(); /** + * Sets whether this operation is a query (C++ "const".) + */ + void setConst(bool b); + + /** + * Returns whether this operation is a query (C++ "const".) + */ + bool getConst() const; + + /** * Saves to the <UML:Operation> XMI element. */ void saveToXMI( QDomDocument & qDoc, QDomElement & qElement ); @@ -196,6 +206,7 @@ private: UMLAttributeList m_List; + bool m_bConst; }; #endif
You need to log in before you can comment on or make changes to this bug.