📄 code_c++_intro.html
字号:
is accessible to all organisms that may need to make use of it.<p>The final data element is <font color="#0000AA">hardware</font>, a pointerto an object of type <font color="#880000">cHardwareBase</font>. This variableis a pointer for a different reason than the genotype. Where a single genotypeis shared by many different organisms, each organism does possess its ownhardware. But in implementing Avida, I allowed many different kinds ofhardware to be available, where any of them can be at the other end ofthat hardware pointer. The cHardwareBase class is used as an interfaceto the actual hardware that is used. This is explained in more detail laterin the section on "Inherited Classes". For the moment, the key idea isthat a pointer can sometimes point to a general type of object, not justthose of a very specific class.<h3>Description of Methods</h3>Class descriptions (with limited exceptions) must contain two specificmethods called the <b>constructor</b> and the <b>destructor</b>. The constructoralways has the same name as the class (it's called <font color="#008800">cOrganism(...)</font>in this case), and is executed in order to create a new object of thatclass. The arguments for the constructor must include all of the informationrequired to build on object of the desired class. For an organism, we needthe genome of that organism, an interface to the population it will bein, and the environment it needs to operate under. The method is not definedhere, only <b>declared</b>. A declared method must be defined elsewherein the program. All methods must be, at least, declared in the class definition.Note that if there are many ways to create an object, multiple constructorsare allowed as long as they take different inputs.<p>Whereas the constructor is called when an object is created, the destructoris called when the object is destroyed, whereupon it must do any cleanup,such as freeing allocated memory (see the section on memory managementbelow). The name of a destructor is always the same as the class name,but with a tilde ('~') in front of it. Thus, the cOrganism's destructoris called <font color="#008800">~cOrganism()</font>. A destructor can nevertake any arguments, and there must be only one of them in a class definition.<p>The next group of five methods are all called when an organism needsto perform some behavior, which in all of these cases involves it interactingwith the population. For example, if you need to know at whom an organismis facing, you can call the method<font color="#008800">GetNeighbor()</font>on it, and a pointer to the neighbor currently faced will be returned.Likewise, if you need to kill an organism, you can call the method<font color="#008800">Die()</font><font color="#000000">on it, and it will be terminated. Since each of these require interactionon the population level, the population itself takes care of the bulk ofthe functionality.</font><p>The next pair of methods,<font color="#008800">DoInput(...)</font> and<font color="#008800">DoOutput(...)</font>are used to monitor when the organism triggers a task. Whenever the organismrequests a new input number or outputs a processed number, the DoInputor DoOutput method is called with the value being sent in/out, the currentstate of the input buffer (that is, all values that have been input thusfar), and the current state of the output buffer (all of the values thatthe organism has output over its lifetime). The buffers are scanned fortask completion, and any relevant reactions are triggered.<p>The "Accessors" are methods that provide access to otherwise privatedata. For example, the method <font color="#008800">GetGenome()</font>will literally pass the genome of the organism to the object that callsit. In particular, the hardware object associated with an organismwill often call <font color="#008800">GetPhenotype()</font> in order to get the current state of the organism's phenotype and update it withsomething new the organism has done. Several things to take noteof here. In the first two accessors, the name of the class beingreturned is followed by an ampersand ('&'). This means that theactual object is being passed back, and not just a copy of all the valuescontained in it. See the next section on pointers, references, andvalues for more information about this. Also, in the very first accessor,the keyword "<tt>const</tt>" is used twice. The first time is tosay that the object being passed out of the method is constant (that is,the programmer should be warned if somewhere else in the code it is beingchanged) and the second time is to say that the actions of this methodwill never change anything about the object they are being run on (thatis, the object is being left constant even when the method is run.) The net effect of this is that an object marked const can only have constmethods run on it. The compiler will assume that a non-const method beingrun will make a change to the object, and is therefore an error.<p>Finally, we have the pair of methods<font color="#008800">SaveState(...)</font>and <font color="#008800">LoadState(...)</font> that are used when Avidaruns are being saved to or resumed from file. The input "<tt>ofstream</tt>"stands for Output File Stream, and contains information about the filethat data is being written to. Likewise, an "<tt>ifstream</tt>" objectis an Input File Stream and used when a C++ program needs to read informationfrom a file.<p><font color="#000000">This section has contained information about aparticular C++ class found in Avida. The next sections will moregenerally explain some of the principles of the language. If youhaven't already, now might be a good time to take a deep breath beforeyou dive back in.</font><h3><font color="#000000">Pointers, References, and Values</font></h3><font color="#000000">The three ways of passing information around in aC++ program is through sending a pointer to the location of that information,sending a reference to it, or actually just sending the value of the information. For the moment, lets consider the return value of a method. Considerthe three methods below:</font><p><tt><font color="#000000"> </font><font color="#880000">cGenome</font><font color="#008800">GetGenomeValue()</font><font color="#000000">;</font></tt><br><tt><font color="#000000"> </font><font color="#880000">cGenome</font><font color="#000000">* </font><font color="#008800">GetGenomePointer()</font><font color="#000000">;</font></tt><br><tt><font color="#000000"> </font><font color="#880000">cGenome</font><font color="#000000">& </font><font color="#008800">GetGenomeReference()</font><font color="#000000">;</font></tt><p>These three cases are all very different. In the first case ("<b>Pass-by-Value</b>"),the value of the genome in question is returned. That means that the genomebeing returned is analyzed, and the exact sequence of instruction in itare sent to the object calling this method. Once the requesting objectgets this information, however, any changes made to it do <i>not</i> affectthe original genome that was copied. The second case ("<b>Pass-by-Pointer</b>"),only a few bytes of information are returned that give the location inmemory of this genome. The requesting object can then go and modify thatmemory if it chooses to, but it must first "resolve" the pointer to doso. Finally, the last case ("<b>Pass-by-Reference</b>") actuallypasses the whole object out. It is used in a very similar way topass-by-value, but any changes made to the genome after it is passed outwill affect the genome in the actual organism itself! Pass-by-referencedoes not add any new functionality over pass-by-pointer, but in practiceit is often easier to use.<h3>Memory Management</h3>Memory management in C++ can be as simple or complicated as the programmerwants it to be. If you never explicitly allocate a chunk of memory, thanyou never need to worry about freeing it up when you're done using it.However, there are many occasions where a program can be made faster ormore flexible by dynamically allocating objects. The command <b><tt>new</tt></b>is used to allocate memory; for example if you wanted to allocate memoryfor a new genome containing 100 instructions, you could type:<p><tt> <font color="#880000">cGenome</font> * <font color="#0000AA">created_genome</font>= new <font color="#008800">cGenome(</font>100<font color="#008800">)</font><font color="#000000">;</font></tt><p><font color="#000000">The variable "created_genome" that is definedas a pointer to a memory location containing a genome. This is assignedto a newly allocated genome in memory, which is the return value of thenew command. The cGenome constructor (called with new) takes as anargument a single number that is the sequence length of the genome.</font><p><font color="#000000">Unfortunately, C++ won't know when we're doneusing this genome. If we need to create many different genomes andwe only use each of them once, our memory can rapidly fill up. So,we need to tell it. Thus, when we're done using it, we type:</font><p><tt><font color="#000000"> free </font><font color="#0000AA">created_genome</font><font color="#000000">;</font></tt><p><font color="#000000">And the memory pointed to by the created_genomevariable will be freed up.</font><p><font color="#000000">An excellent example of when allocation and freeingof memory is employed in avida is with the genotype. Every time anew genotype is created during evolution, avida needs to allocate a newobject of class cGenotype. During the course of a run, millions ofgenotypes may be created, so we need to be sure to free genotypes wheneverthey will no longer be needed in the run.</font><h3><font color="#000000">Inherited Classes</font></h3><font color="#000000">One of the beauties of C++ is that well written codeis inherently very reusable. As part of that, there is the conceptof the <b>inhereted class</b> (sometimes called a <b>derived class</b>). When a new class is built in C++, it is possible to build it off of anexisting class, then referred to as its <b>base class</b>. The derivedclass will have access to all of the methods in the base class, and can<b>overload</b> them; that is, it can change how any of those methods operate.</font><p><font color="#000000">For example, in the Avida scheduler, we use aclass called </font><font color="#880000">cSchedule</font><font color="#000000">to determine which organism's virtual CPU executes the next instruction. Well, this cSchedule object is not all that clever. In fact, allthat it does is run through the list or organisms that need to go, letsthem each execute a single instruction, and then does it all over again. But sometimes we need to make some organisms execute instructions at afaster rate than others. For that reason, I derived several classesincluding </font><font color="#880000">cIntegratedSchedule</font><font color="#000000">,which takes in a merit value for each organism, and assigns CPU cyclesproportional to that merit. Since this new class uses cSchedule asits base class, it can be dynamically plugged in during run time, afterlooking at what the user chooses in the genesis file.</font><p><font color="#000000">If a method is not implemented in a base class(left to be implemented in the derived classes) it is called an <b>abstract</b>method. If a base class does not implement <i>any</i> of its methodsand is only used in order to specify what methods need to be included inthe derived classes, it is referred to as an <b>abstract base class</b>and is used simply as an interface protocol to the derived classes. An example in avida where this is used is the hardware. The class</font><font color="#880000">cHardwareBase</font><font color="#000000">is an abstract base class; the reason it is abstract is because in principle,any kind of underlying virtual hardware should be allowed. Currently,only one is implemented called </font><font color="#880000">cHardwareCPU</font><font color="#000000">(a virtual CPU), but I have lots of ideas to have, such as a neural networkrunning the organisms.</font><h3>Links:</h3><menu><li><a href="http://www.intap.net/~drw/cpp/">Online C++ Tutorial</a></li><li><a href="http://www.cplusplus.com/doc/tutorial/">Another Tutorial</a></li><li><a href="http://www.quiver.freeserve.co.uk/OOP1.htm">Object Oriented ConceptsTutorial</a></li><li><a href="http://www.research.att.com/~bs/glossary.html">A Glossary of C++Terms</a></li></menu></body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -