class V {public: virtual ~V(){}}; //Virtual Base Class
class G: virtual public V{}; //Common ancestor for base classes
class B1: public G{};
class B2{}; //Non-polymorphic class
class B3: public G{};
class D: public B1, public B2, public B3 {};
class I{ public: virtual ~I(){}}; //Independent, unrelated Class
int main(int argc, char* argv[])
{
D d;
D* pdd=&d;
B1* pb1d=&d; //No casts needed
B2* pb2d=&d;
B3* pb3d=&d;
V* pvd=&d;
//G* pgd=&d; //Compile-error, ambiguous
// I* pi1d=&d; //Cast needed. Compile error.
I* pi1d=(I*)&d; //No compile error, but semantically wrong. Address gets assigned.
//I* pi1d=static_cast<I*>(&d); //Compile error
//Upcasting
B1* pb1= dynamic_cast<B1*>(pdd); // = pb1d
B2* pb2= dynamic_cast<B2*>(pdd); // = pb2d
B3* pb3= dynamic_cast<B3*>(pdd); // = pb3d
G* g1 = dynamic_cast<G*>(pdd); //No compile-error, but null because ambiguous
G* g2 = reinterpret_cast<G*>(pdd); //No compile-error, nothing
//G* g3 = static_cast<G*>(pdd); //Compile-error, but null because ambiguous
//Downcasting
D* pdd1 = dynamic_cast<D*>(pb1d); //downcast, B1 must be polymorphic
//D* pdd = dynamic_cast<D*>(pb2d); //downcast, B2 not polymorphic. Compile error.
G* g3= dynamic_cast<G*>(pvd); //ambiguous downcast, = null, compiles in C++ not in Comeau
// G* g4= static_cast<G*>(pvd); //ambiguous downcast, = null
//Crosscasting
I* pi= dynamic_cast<I*>(pdd); //pi will be null
I* pi2= reinterpret_cast<I*>(pdd); //pi2 will be equal to pdd
//I& ri= dynamic_cast<I&>(*pd); //throws an exception
B3* pb31= dynamic_cast<B3*> (pb1d);
return 0;
}
Wednesday, June 09, 2010
C++ casts Demystified
Saturday, May 29, 2010
Rethink About Reuse
1. Three pillars of OO
1. inheritance
2. encapsulation
3. polymorphism
1. overload
2. coercion
3. parametric
4. runtime inclusion
2. object oriented styles
1. prototype-based
2. object-based
3. dynamically typed
4. statically typed
3. object destruction policy
1. scope-nound
2. explicit
3. reference-based
4. GC
4. reuse is actually use!
5. use chairs to make a bed is reuse
6. using it again to sit is just use
7. inheritance-based
8. interface-based
9. challenge is to organize code
10. if you are not doing much, you become uncomfortable
11. "Adaptation"?
12. you cannot have virtual template functions
Saturday, February 20, 2010
PAPPADOM Framework
Calling it PAPPADOM = Portable Application Providing Persistence Atop DOM (Document Object Model)
PAPPADOM is a package consisting of
* Prototype Javascript framework
* Miscellaneous UI components - menubars, menu etc
* Persistence - save stuff
Advantages
* Portable - web-browsers supporting Javascript is all you need
* Open Data - data is stored within the HTML file and hence is accessible.
Examples:
Neptuner UBoat: http://neptuner.googlecode.com/files/demo_uboat_neptuner_0_20.zip
Memonaut: http://memonaut.googlecode.com
Just a fancy name...
Friday, February 12, 2010
Containers: Stick to basic types initially
There might be quite a bit of boiler-plate code to add to the class Student before you can use STL containers to contain Student objects. Rather than getting your program’s core functionality up, you may find yourself just plugging in mundane code into your data-types, not to talk about all those strange-looking and mostly unreadable error-messages.
Example:
class Student
{
string m_sName;
RollNumber m_xID;
Grade m_xGrade;
}
Tip 1: Work with pointers to your class. The use of the pointer also makes for better efficiency: no copies of your objects!
multimap<Grade, Student*> gaGradeReport;
Again depending on the contents of the class Grade, the compiler may squeal! It needs a comparison type LessThan before it can work…which brings me to Tip 2…
Tip 2: Use basic data-types for your key in associative containers like std::set, std::map etc. The easiest way to do it is to provide a conversion operator to a basic type for your key class.
multimap<short, Student*> gaGradeReport;Solution:
//After providing conversion to short
class Grade{... operator short() {...}}
Implement your program on these lines, get it working and then do the boiler-plate stuff.
Here’s how you may do the grade-report task:
//Add the student info
for(..)//Iterate through the student objects one by oneSummary:
(
//Get the address of student record in pxStudent
gaGradeReport.insert(pair<short, Student*>(short(pxStudent->m_xGrade),pxStudent);
}
//Print the GradeReport multimap
for(..//each grade)
{
for(..//each record in range)
{//print the record}
}
Work with basic data-types (pointers are basic data-types) for STL containers for more rapid development. Plug in the boiler-plate later.
Thursday, January 28, 2010
Schedule Task, View Dependencies
Sunday, January 17, 2010
Make It Fast!
- Self-maintaining: No need for manually adding files.
- Quick-and-dirty: Get started fast!
Here goes:
SOURCE_FILES= $(wildcard *.cpp) ../../commando/sonar/Sonar.cpp
# Automatically gets the file-list from the directory!
# Add extra files from other dirs at the end if needed (Sonar.cpp above)
OBJS=$(patsubst %.cpp, %.o,$(SOURCE_FILES))
# Rule for specifying object file list
# The rest of this is standard make-file stuff COMPILER=g++
CFLAGS= -W -g -O0 -fexceptions -finline-functions -D_THREAD_SAFE -fpack-struct=4
#Compiler options
LIBS= -lboost_filesystem
#Libraries to link to
SEARCHDIRS = -I../inc -L../lib#Include and library directories
TARGET= ../../homebase/linux/nuboat
# Output file
.PHONY:all
all: $(TARGET)
$(TARGET): $(OBJS)
$(COMPILER) $(CFLAGS) $(SEARCHDIRS) $(GLOBALS) $(OBJS) $(LIBS) -o $(TARGET)
%.o: %.cpp
$(COMPILER) $(CFLAGS) $(SEARCHDIRS) $(GLOBALS) -o $@ -c $<
.PHONY:clean
clean:
-rm -f $(OBJS) $(TARGET)
You can use this so long as you don't have source files floating around in the Makefile's directory, which should not be included in the build.
Sunday, December 13, 2009
Neptuner Coding Guidelines
|
Wednesday, September 16, 2009
I Could Have Done It Too
Monday, June 29, 2009
Thomanujan Number - 1229
Thanks to Jeswin for pointing out bug in code.
:S :( Sheepish smile
Wednesday, May 27, 2009
Baseline Semantics
The term Baseline can often be a source of confusion.
In my experience with Configuration Management and other tools (Microsoft Project etc), a baseline is anything “that can serve as a basis for comparison” – this may or may not be approved. SVN, in fact, skirts this baseline issue by defining the alternate terminology “tag” for the same thing!
I believe our problems stem from the–
1) Informal use of baseline as a verb, with the meaning ‘to approve’.
2) Lack of formalization of what type of baseline (and there are many kinds, refer below!) we refer to when we generically use the term baseline
References
Dictionary definition:
Noun: baseline
1. An imaginary line or standard by which things are measured or compared
(TJ: Other meanings for sake of completeness, also note “imaginary” J in 1)
2. The back line bounding each end of a tennis or handball court; when serving the server must not step over this line
3. The lines a baseball player must follow while running the bases
Wikipedia mentions:
Generally, a baseline may be a single work product, or set of work products that can be used as a logical basis for comparison. A baseline may also be established (whose work products meet certain criteria) as the basis for subsequent select activities. Such activities may be attributed with formal approval.
There are different kinds of baselines (from Wikipedia).
Functional Baseline: initial specifications established; contract, etc. Allocated Baseline: state of work products once requirements are approved
Developmental Baseline: state of work products amid development
Product Baseline: contains the releasable contents of the project
Others, based upon proprietary business practices
CMMi itself defines it multiply as (from CMMi-DEV 1.2 )
A baseline is a set of specifications or work products that has been formally reviewed and agreed on, that thereafter serves as the basis for further development or delivery, and that can be changed only through change control procedures. A baseline represents the assignment of an identifier to a configuration item or a collection of configuration items and associated entities. As a product evolves, several baselines may be used to control its development and testing.
For Systems Engineering
One common set of baselines includes the system-level requirements, system-element-level design requirements, and the product definition at the end of development/beginning of production. These are typically referred to as the “functional baseline,” “allocated baseline,” and “product baseline.”
For Software Engineering
A software baseline can be a set of requirements, design, source code files and the associated executable code, build files, and user documentation (associated entities) that have been assigned a unique identifier.
TJ:
In my opinion, attaching extra, “holy” meanings to an-already polymorphic word would not be appropriate. It would be a classic case of jargon-clash and would lead to inter-personal communication problems and possibly conflict!
It would also mean an incurrence of training (un-training) overhead and would be the proverbial seed for discontent in a new adopter.
Thursday, January 01, 2009
INTEGRATE – 2008 - Changes done for 2K9
0 error(s), 0 warning(s), 1 greeting(s)
Wish you a Happy New Year!
Log attached.
Sunday, December 14, 2008
Recipe - Do Something To Each File In Directory
To do the same operation on each file, in Windows, you can use the for command.
for /F %i in ('dir *.dbg /s/b ') do @del %i
The above example deletes all *.dbg files under the current directory
Explanation
for /F %i ......... for each %i
in('dir *.dbg /s/b ') ..... in the list returned by the command. dir /s specifies a recursive search, /b causes it to to output just a list, without the file details
do @del %i ...... del %i is the command to delete the file. @ suppresses the display of the command
Recipe Syntax
for /F {%var} in ('{list-builder-command}
Tuesday, November 11, 2008
Digital Peer
http://www.digitalpeer.com/
There are tips, tutorials and articles here.
Hope it stays online!
Saturday, July 26, 2008
Monday, January 28, 2008
Perly Gates
Replacing string content with another string when both could contain backslashes.
Explanation:
Basically, you have to use \Q to escape. Otherwise, the contents of the strings (search & replace strings) will be interpreted as escape sequences.
Example:
The following is an extract from a script to get the relative path of a file with respect to a base-directory.
#!/usr/bin/perl
$BASE = "d:\source\";
print "Base : $BASE\n";
$TARGET = "d:\source\temp\test.txt";
print "Original : $TARGET\n";
$TARGET =~ s/\Q$BASE//;
#Replacing with null string
#syntax for replace:
#TargetString =~ is s/SearchString/ReplaceString/
print "Modified : $TARGET\n";
#Target becomes "temp\test.txt"
Tip 2:
Replace backslashes with forward slash.
If you do this the regular way, the regex you write will likely look like a squiggly drawing :) Something like /\/\\/ ;), which is a pain to read or debug.
#!/usr/bin/perl
# In Perl, any character can be used to delimit the regex! Here, using @ as separator
$STRING =~ s@\\@/@g;
Yeah, it's still ugly and we need to escape the backslash as \\, but that's they way it goes. Use this tip whenever you need to replace
Tip 3:
Get command line output into a variable
Here's a function to do this. Takes two parameters, the command-string to execute and a boolean option for showing the output on the display.
sub getCommandOutput
{
my ($COMMAND, $DISPLAYOUTPUT) = @_;
open(COMMAND_OUTPUT, "$COMMAND 2 >&1 |");
my @OUTPUTLINES = <COMMAND_OUTPUT>;
chomp(@OUTPUTLINES);
close(COMMAND_OUTPUT);
foreach $OUTPUTLINE(@OUTPUTLINES){
print "\n$OUTPUTLINE" if $DISPLAYOUTPUT;
}
print("\n") if ($DISPLAYOUTPUT);
return @OUTPUTLINES;
}
# TODO You may want to capture the error stream separately
Thursday, December 13, 2007
Commentstipation
Code should be self-explanatory and hence self-commenting, as far as possible. But this definitely does not mean that there should be no comments.
Good comments are hard to come by because of -
a) I-Am-A-Programmer-Not-A-Writer attitude
Well, you are a writer too.
b) "I don't know English that well" excuse
Grammatical errors are fine, spelling mistakes are also OK. Write in your native tongue and translate it, if need be. And, if what the code does is that tough to explain, then it's also the more reason to document it, it probably needs to be documented!
Remember the programming adage: Documentation is like sex, something is better than nothing! ;-) But, it must be said, inaccurate documentation is worse than no documentation. An addition to the adage is perhaps needed...having it the wrong way is probably worse than not having it at all! ;-)
TIPS
--------
* A comment should, at the very least, explain and focus on what is special in the block of code. A very good comment also explain why it is being done.
* The best comments explain the what and the why succinctly.
* How to comment
1. Ask yourself "What?"
2. Ask yourself "Why?"
3. Write what you would say to someone so that he could do what you have done. Use simple language. (This point intentionally abstruse, to serve as a memory-aid)
4. Review and edit what you have written, the best you can.
* Do not state the obvious! But also remember that what is obvious to you may not be obvious to another person. It's a thin line between advising and preaching.
Code like:
x=0; // Assigning the value 0 to the variable x
is a big no-no. Do not insult the intelligence of the reader. Plus, you'll have to scroll more while editing the code!
Monday, December 10, 2007
Coding Nirvana - Cryptic Mystic Droppings
FROM THE ELEVATED STATE
OF CODING NIRVANA
1. Code is just symbols.
2. Code needs a Thread of Life to achieve its Purpose.
3. It's all about the data.
4. It's all virtual. It can be faked but it doesn't really matter; it isn't really matter anyway.
More on each of these droppings (shit!) later.
Saturday, December 08, 2007
Coding Nirvana - Four Noble Truths
FROM THE ELEVATED STATE
OF CODING NIRVANA
-----------------------------------------------------------
FOUR NOBLE TRUTHS
-----------------------------------------------------------
1. There is suffering
2. There is a cause of suffering. The cause is "Copy-paste"
3. There is the cessation of suffering - "Abstraction Of Commonality"
4. There is a way leading to the cessation of suffering — the Noble Eightfold Path
------------------------------------------------------------
"Copy-paste is the root cause of all programming suffering. Copy-paste is evil. The Eternal Conflict is between copy-paste and the Abstraction of Commonality."
- The Virtual Mystic
Sunday, November 25, 2007
C Powershot - Pointers
---------
How should one interpret the following lines of C?
int *p;
"easy! p is an integer pointer!"
int **p;
"p is a pointer to an integer pointer" or perhaps you might say "p is a double pointer to an integer"
int ***p;
"hmm...er..ahem..why would anybody use such a thing! *@#$ ?"
POWERSHOTS - Interpreting a pointer declaration
----------------------------------------------------------------
The interpretations given i n the preceding section, even if somewhat correct, do not scale and could inhibit our ability to understand alien (written by other people) code. The words influence the way we think, so it's necessary that we choose the right abstractions. For example, if a pointer is 4 bytes, why shouldn't a double pointer be 8 bytes? :-) The right abstraction would not even allow us to stray down such lines of thought!
Here's a better way to interpret pointers.
SNN1.1 Pointers are variables which can hold the address of a memory location, usually the address of a variable.
Pointer Part
Consider the statement
int *p;
What the "*p;" portion of the statement says is only this : p is a pointer variable
Let's call the "* p" portion here the pointer part of the pointer declaration. It tells us this much p is a pointer and * operation can be applied on it.
CPS1.1 Whatever follows the * symbol is the pointer variable.
SNN1.2 Pointer variables in C have the * operation (fancier name: dereference) defined on them.
The deference operation gets the contents of the memory location held in the pointer. That is, if you dereference a pointer, you get what the pointer points to.
****
Type Part
Consider, again, the statement:
int *p;
What the "int " part means is this: when you apply the * operator on p, what you get will be interpreted as an integer. It can be used as an integer.
Let's call the "int " portion here the type part of the pointer declaration.
CPS1.2 Whatever remains in the statement after you blank out the pointer portion will be the type of what you get when you dereference the pointer.
FINGER-HIDING TECHNIQUE: Just hide the *p section with your finger, what remains is the type part. This finger-hiding technique can come in handy in other situations as well. It's nifty and mighty useful. It is an application of what I call the typedef principle, we will come to that in a later episode.
Summary:
Pointer declaration = pointer part + type part.
To reiterate, int *p means: p is a pointer, which will be dereferenced as "int"
EXAMPLES
---------------
EX1
int **p;
Pointer part: *p ====> p is a pointer
Type part: int * ====> when you dereference p, what you get should be interpreted as"int *".
You already know what int * means according to the power-shots! This has to be done repeatedly.
EX2
int *p[6][6];
Pointer part: *p =====> p is a pointer
Type part: int __ [6][6] ====> when you dereference p, what you get should be interpreted as "int [6][6]".
This is an array of integers with 6 rows and 6 columns. int
EX3
int (*p)(int i, int j);
Pointer part: *p =====> p is a pointer. The parentheses are required because otherwise due to precedence rule, the * would be associated with int and not p.
Type part: int __ (int i, int j) ==>when you dereference p, the type of data you'll get is "int (int i, int j) ".
This is an integer function which takes two parameters.
Yup, p is a function pointer. (But you do know better now, right? p is just a pointer, when you dereference it you will get something that can be used as a function)
EX4
int (*p(int a)) (int *b);
Pointer-part: *p ====> p is a pointer
Type-part: ( __ (int a)) ==> *p is a function.
So, p is a pointer to a function.
The remaining part is the type of the function.
Finally, p is a pointer to a function, which takes an integer, and returns a function which takes an int* parameter and returns an int!
Aside: Actually, the type part of the declaration is what is within the parentheses enclosing the pointer-part, but that would have confused you; also, this is not needed in the vast majority of cases. Parentheses always rule and dictate, as you should have guessed from the previous example as well!
You'd be much better off using typedefs for complex declarations like this one. But that does not mean that one should not know how exactly it is being interpreted. :-) More on typedefs later. For the time being, referring you to http://www.gotw.ca/gotw/046.htm where this particular example was taken from.
POSSIBLE GOTCHAS
-----------------------------------------
1. Function-pointers can, on some architectures, require more space than normal pointers. If code memory uses a different addressing size/scheme, for instance. Have not encountered this though.
2. Please use parentheses liberally(but judiciously!) inside declarations and the * operator while dereferencing the pointer. These are often skipped and lead to confusing (nah, 'misinterpretable') code.