Arv

Det finns tre relationer i OOP. HAR relationen, KÄNNER TILL relationen och ÄR relationen. ÄR relationen beskrivs med ARV.Man åstadkommer arv genom subklasser

till klasser man radan har.Man skapar klasser som delvis är lika men ändå olika och det beskrivs med POLYFORMA klasser. för objekt som tillhör polyforma klasser kan det finnas operationer med samma namn, men som utför olika saker beroende på objektet.

Dynamisk bindning eller sen bindning – bindningen sker inte förrän man kör programmet.

Statisk bindning eller tidig bindning – bindningen ske när man kompilerar koden.

 

Konstruktoer destruktorer vänfunktioner och tilldelningsoperatorn ärvs inte. Man kan

ärva i flera led. Basklass till subklass till ytterligare subklasser:

 

Härledda klasser

class D: tillgänglighet (public, protected private) B {

…….

};

Klassen D är direct härledd (derived) från klassen B. Klassen B är en direkt basklass till D

D ärver alla medlemmar från B.

Undantag. Konstruktorer, destruktorer, vänfunktioner och tilldelningsoperatorn =

Medlemmar med samma namn gömd.

class D2 : tillgänglighet D{

….

};

Klassen D2 är indirekt härledd från klassen B. Klassen B är en indirekt basklass till D2

D2 ärver alla medlemmar från B och D.

 

 

Objekt som tillhör en härledd klass initieras som andra objekt med hjälp av konstruktorn. När en sådan konstruktor anropas måste även de datamedlemmar som ÄRVTS från basklassen initieras. Detta sker genom att konstruktorn för basklassen anropas.

Konstruktorn för basklassen anropas alltid inna datamedlemmarna i den härledda klassen initieras.

 

Konstruktorer vid arv

Före en härledd klass D med den direkta basklassen B gäller:

I en konstruktor för D kan man i initieringslistan explicit anropa en konstruktor för basklassen:

 D::D(parametrar) : B(parametrar), …. {satser}

Har detta ej gjorts, anropas aoutomatiskt B:s default konstruktor.

Om klassen  D har en aoutomatiskt genererad default konstruktor så anropas i denna basklassens defalt konstruktor.

 

Initieringsordning i en konstruktor:

 

Destruktorer

Destruktorerna ärvs inte. En destruktor används i normala fall bara när man allokerat minne som behöver frigöras. Allting sker i motsatt ordning mot konstruktorerna. Det innebär att destruktorn för den mest härledda klassen exekveras först.

 

Tillgänglighet

private      kan bara användas av medlemsfunktioner av klassen och friend funktioner

protected  medlemsfunktioner, friendfunktioner och härledda funktioner

public       kan användas överallt

       class D :  private B      { ……..}

       class D :  protected  B { …….. }

       class D :  public B       { ..…… }

·        privata medlemmar i B blir aldrig synliga någon annanstans än i B oberoende av arv

·        privat arv (private:) alla medlemmar i B som är skyddade eller synliga blir privata i D

·        skyddat arv (protected:) alla medlemmar i B som är skyddade eller synliga blir skyddade i D.

·        synligt arv (public:) alla medlemmar i B som är synliga blir synliga i D. Synligt arv är det vanligaste (public).

 

Polyformism

Vid typade programspråk, alltså där man kan ha olika funktioner beroende på vilka typer parametrarna har (överlagring), bestäms anropen till funktionerna vid kompileringen. Man säger att anropet binds till funktionen.  Via mallar kan man också göra generiska funktioner

s.k. templates, där elementen inte behöver vara av fördefinierade typer, int, double osv utan

av godtycklig typ. Överlagring och generiska programenheter är två former som i programmeringssammanhang kallas för polyformism (mångformighet). Både när det gäller överlagring och generisk programmering sker bindning vid kompilering av programmet. Detta kallas för statisk bindning eller tidig bindning.  Man kan också ha dynamisk bindning eller sen bindning och då sker inte bindningen förrän vid exekveringen av programmet. För att detta skall vara möjligt använder man sig av arv och virtuella funktioner. Via pekare får man sedan den sena bindningen vid exekverandet av programmet. En klass som har virtuella funktioner kallas för polyform klass.

Begrepp:

 

OBS för att få virtuella funktioner måste man ha samma parametrar och returtyp på funktionerna. Gör man inte det döljs den virtuella funktionen i bas klassen.

 

Dynamisk bindning

Den aktuella funktionen måste deklareras som VIRTUELL i basklassen.

virtual returtyp f(parametrar);

 

Omdeklareras i subklasserna med exakt samma parametrar och retur typ. (Ett speciellt undantag finns beträffande returtypen) fungera ej på min kompilator

Ordet virtual behöver ej upprepas.

 

Statisk typ – Den typ ett uttryck har enligt deklarationen

Dynamisk typ – Den typ ett uttryck har vid exekveringen

 

anrop av virtuell funktion:

p->f(..);  //p är en pekare

r.f(…),  //r är en referens

 

Vilken funktion som anropas bestäms av p:s och r:s dynamiska typ

 

 

typeid och dynamic_cast

/* fungerar inte i VisualC++6

    if(typeid(*fp) == typeid(Personbil))

        cout << "Detta är en perosnbil" << endl;

    else if(typeid(*fp) == typeid(Buss))

        cout << "Detta är en buss" << endl;

    else if(typeid(*fp) == typeid(Minibuss))

        cout << "Detta är en minibuss" << endl;

    else if(typeid(*fp) == typeid(Lastbil))

        cout << "Detta är en lastbil" << endl;

        */

    cout << typeid( fp).name() << endl; //ger utskrift: class Fordon*

 

Filen typeinfo inkluderas

typeid(*p) == typeid(C)  //p = pekare

eller

typeid( r) == typeid(C)  //r = referens

 

typeid(*p).name() //ger en textsträng med namnet på klassen

eller

typeid( r).name()  // ger en textsträng med namnet på klassen

 

dynamic_cast<C*>(p) //p omvandlas till typ pekare till C, annars 0

dynamic_cast<C&>(r) //r omvandlas till typ referens till C, annars genereras bad_cast

 

Virtuella destruktorer

Deklarera alltid en virtuell destruktor om klassen skall vara en basklass för andra klasser.

 

Abstrakta klasser

En klass som innehåller minst en ren virtuell funktion kallas för abstrakt klass

förväxla den inte med abstrakta datatyper = typer som man definierar själv.

En virtuell funktion (pure virtual function) saknar implementering.

Ex virtual void ge_info() = 0; //nollan markerar att det är en virtuell funktion

En abstrakt klass blir ett mönster för de primitiva funktioner som skall finnas och det är inte meningen att man skall göra ett objekt av den.

 

En medlemsfunktion kan deklareras som ren virtuell funktion

virtual resultattyp f(parametrar) = 0;

 

Multipelt arv

En klass kan ha flera direkta basklasser

class D : tillgänglighet B1, tillgänglighet B2 ….{

    deklarationer av egna medlemmar

};

Varje bas klass ingår i sin helhet som ett subobjekt. Alla medlemmar från alla basklasser ärvs.

Namnkonflikter kan uppstå men löses med operatorn ::

 

en virtuell basklass v ingår som subobjekt exakt en gång i ett objekt.

class C : tillgänglighet virtual V {

deklarationer av egna medlemmar

};

 

 

Exceptionella händelser

När man programmerar använder man assert från include filen <cassert> för att testa villkoret. Är det inte sant avbryts programmet. Det finns inga möjligheter att fortsätta med programkörningen.

 

Klassen exeption har rutiner för felrutiner. I filen stdexcept finns andra rutiner och exception

också, så det räcker att ladda in stdexcept.

exception

logic error                                                                       runtime_error

domain_error                                                                                                     

invalid_argument                                                                                                        range_error

length_error                                                                                                           overflow_error

out_of_range

 

 

 

 

throw uttryck

där uttryck kan vara av godtycklig typ. Den normala exekveringen avbryts när en throw sats exekveras. Bäst är att använda en standard klass från exception throw s(”text”) eller någon

egen klass härledd från klassen exeception. du måste inkludera filen <stexcept>

 

Att fånga exception:

  1. Försök att vidta någon lämplig åtgärd så att programmet kan fortsätta
  2. Identifiera felet och skicka det till någon annan programenhet för att åtgärda felet
  3. Identifiera felet, men gör ingenting utan avsluta programmet – abort();

 

try block

try {

    satser

    throw overflow_error(”Fel i x”);

}

catch (parameter) {

  satser

}

catch (parameter){

  satser

}

catch (…){   //tar alla fel

  satser

}

 

Specifikation av exeptionella händelser

I en funktionsdeklaration kan man lägga till en händelselista sits:

retur typ f(parametrar) throw(T1, T2, T3 .. );

throw(overflow_error, out_of_range, bad_exception)

Funktionen kan då bara generera exceptionella händelser av de typer som anges I listan.

En tom händelselista innebär att inga exceptionella händelser kan genereras av funktionen.

returtyp f(parametrar) throw();

Saknas händelselista kan händelser av alla typer genereras:

returtyp f(parametrar);

 

Om det genereras en exceptionell händelse av en typ som inte är angiven på händelselistan, anropas funktionen unexpected, som avbryter programmet.

unexpected kan ersättas med egen funktion:

 

set_unexpected(namn_på_egen_funktion);

Denna får generera händelse av typen bad_exception.

void my_unexpected()

{throw bad_exception;}

 

set_unexpected(my_unexpected);

 

 

 

 

 

Containerklasser och algoritmbibliotek

 

Klasser som hanterar datasamlingar kallas för containerklasser.

Finns två huvudgrupper:

SEKVENSER och ASSOCIATIVA CONTAINERS

 

SEKVENSER:

till sekvenser räknas också ADAPTERKLASSERNA

 

Det finns också en samling färdiga funktioner som man kan använda för att hantera containerklasserna (ALGORITMER)

Iteratorer

Vector och deque kan behandlas som vanliga fält. Man har möjligheten att indexera för att löpa igenom dem effektivt, men man kan inte använda pekare på dem. Det finns i stället iteratorer. En iterator är en fristående pekarlik variabel som man kopplar till en viss datasamling tex vector eller lista. jIteratorerna kan användas på alla containerklasserna utom adapterklasserna

Man kan också använda iteratorena ihop med klassen string eller med strömmar för läsning och skrivning.

Iteratorerna används för:

 

Den kraftfullaste iteratorn är random-access iterator som kan utföra pekaritmetik

#include <iostream>

#include <vector>

#include <string>

#include <deque>

using namespace std;

 

void main(){

    vector<double> v(4);

 

    vector<double>::iterator it;

    int k =10;

    it = v.begin();  //iteratorn pekar på första elementet

    it = v.end();    //iteratorn pekar på sista elementet

    for(it=v.begin(); it != v.end(); it++)

        *it = k++;

 

    for(it=v.begin(); it != v.end(); it++)

       cout << *it << endl;

 

    //löpa igenom ett fält med const

    vector<double>::const_iterator cit; //konstant iterator

 

    for(cit=v.begin(); cit != v.end(); cit++)

       cout << *cit << endl;

 

    //löpa igenom baklänges reverse

     vector<double>::reverse_iterator rit;

 

      for(rit=v.rbegin (); rit != v.rend(); rit++)

       cout << *rit << endl; 

 

    //att använda -> för klasstypen  string

    deque<string> d;

    d.push_front("Pascal"); d.push_front("c");

    d.push_front("c++"); d.push_front("Java");

    for(deque<string>::iterator  j=d.begin(); j != d.end(); j++)

        {

        if (j->at(0) == 'c')

            j->at(0) = 'C';

        cout << *j << " ";

        }

    }

 

Operationer med iteratorer som parametrar

#include <iostream>

#include <vector>

#include <string>

#include <deque>

#include <list>

using namespace std;

 

 

 

void main(){

   

    int a[] = {5,6,7,8,9,10};

    vector<int> v(a, a+4);              //v innehåller {5,6,7,8};

    list<int> l(v.begin(), v.end());    //l innehåller {5,6,7,8};

    //assign finns i form där man ger iteratorer eller pekare som argument

 

    l.assign(a, a+2);   //OBS FEL       //l innehåller {5,6};

    l.insert(l.begin(), 0);             //l innehåller {0,5,6};

    list<int>::iterator  it = l.begin();

    l.insert(++it,3,1);                 //l innehåller {0,1,1,5,6};

 

     //kopierar och skuter in

    l.insert(l.begin(), v.begin(), v.end());

    //l innehåller {5,6,7,8,0,1,1,5,6};

 

    //ta bort ett element

    it = l.begin();

    ++it,++it,++it;

    l.erase (it);                   //l innehåller {5,6,7,0,1,1,5,6};

   

    //ta bort allt utom det sista

    it=l.end();

    l.erase (l.begin(), --it); //l innehåller {6};

   

    l.erase (l.begin() ); //l innehåller {6};

    }

 

 

Iteratorer

Följande typer finns definierade i alla containerklaser. con = container typ(vector eller list)

För klasserna  vector och deque är iteratorerna av kategorin random acces iteratorer och övriga bidirectional iterator.

con::iterator<typ>                                      ++ löper framåt

con::const_iterator<typ>                            ++ löper framåt  endast för avläsning (konstant)

con::const_reverse_iterator<typ>               ++ löper bakåt endast för avläsning

 

Följande operationer finns i alla containerklasser samt i klassen string

begin()           ger iterator som pekar på första elementet

end()              ger iterator som pekar på tänkt element efter det sista tecknet

rbegin             ger en baklängesiterator som pekar på sista elementet

rend()             ger en baklängesiterator som pekar på elementet före det första

 

Följande operationer finns för iteratorer av kategorin forward iterator

(i och j betecknar iteratorer och m en godtycklig medlem i ett objekt av klasstyp)

*i                   ger det element iteratorn i pekar på (avläsning och utskrift)

i ->                samma som (*i).m

++i                 stegar ett steg framåt

i=j                  tilldelning

i==j                jämförelse (finns ej för output iteratorer)

i!=j                 jämförelse (olikhet - finns ej för output iteratorer)

 

För kategorin bidirectional iterator finns alla ovanstående operationer plus följande:

--i                  stegar ett steg bakåt (ger nya värdet)

i--                  stegar ett steg bakåt (ger gamla värdet)

 

För iteratorer av kategorin random-access finns alla ovanstående operationer + följande (jmf med pekararitmetik)

i += n             stegar framiteratorn i n steg

i -= n              stegar bak iteratorn i n steg

i + n               ger en iterator som motsvarar iteratorn i stegad framåt n steg

i – n               ger en iterator som motsvarar iteratorn i stegad bakåt n steg

i = j                ger antalet steg mellan iteratorna i och j

i[n]                 indexering

i < j                undersöker om iteratorn i är mindre än j

i > j                undersöker om iteratorn i är större än j

i <= j              undersöker om iteratorn i är mindre eller lika med  j

i >= j              undersöker om iteratorn i är större eller lika med j

 

Sekvenser: Operationer med iteratorer som parametrar

sekv<typ> s(i,j):                   skapar en sekvens som initieras med intervallet (i,j)

s.assign(i,j);                          tilldelar elementen i intervallet (i,j) till s

s.insert(p,e);                         skjuter in värdet e i pos p

s.insert(p,n,e);                      skjuter in n stycken e i pos p

s.insert(p,i,j);                        skjuter in elementen (i,j) i pos p

erase(p);                              tar bort elementet i pos p

s.erase(p,p2);                       tar bort elementen i intervallet (p,p2) från s

 

Funktions objekt sid 439

Många av standardalgoritmerna har som extra parameter ett s.k. funktionsobjekt som beskriver en operation som skall utföras på elementen i datasamlingen. De finns fyra:

  1. unära predikat (oftast kallad bara predikat) används när man vill löpa igenom en data samling och välja ut vissa element. Returnerar ett värde av typen bool och ska ha parameter av samma typ som elementen i datasamlingen. Predikat är den vanligaste formen av funktionsobjekt. Alla algoritmer som har ett predikat som parameter har ett namn som slutar på _if. ex replace_if, cout_if och find_if
  2. binära predikat. Ett binärt predikat används när man skall jämföra två datasamlingar på något sätt.I vanligaste fallet har ett binärt predikat två parametrar av samma slag som elementen i datasamlingarna. Som resultat ges ett värde av typen bool.
  3. jämförelseoperationer. En jämförelse operation kan användas när man arbetar med datasamlingar som är sorterade eller ska sorteras. En jämförelseoperation har två parametrar av samma typ som elementen i datasmalingarna.
  4. övriga operationer.

 

//användning av pekare till funktioner sid 440

 

#include <iostream>

#include <vector>

#include "iodos.h"

#include <list>

#include <deque>

#include <iterator>

#include <algorithm>

#include <cmath>

using namespace std;

 

void skriv(double x)

    {

    cout << x << " ";

    }

 

bool udda(int i) //funktionen udda är ett predikat

    {

    return i % 2 !=0;

    }

 

bool nastan_lika(double x, double y)

    {

    return  fabs(x-y) <= 1e-10;

    }

int transformera(int x)

    {

    return x*x;

    }

void main(){

     dos_console();

     cout << "Algoritmer" << endl;

     int a[] = {5,6,7,8,9,10,0};

     vector<int> v(a,a+4);

    

     deque<int> d(6,0);     //innehåller {0,0,0,0,0,0}

     copy(v.begin(),v.end(), d.begin());//d innehåller {5,6,7,8,0,0}

   

     for(deque<int>::iterator  j = d.begin(); j!=d.end(); j++)

         cout << *j << " ";

     cout << endl;

     //byter ut alla udda tal mot 0

     replace_if(d.begin(),d.end(), udda,0);

     for(deque<int>::iterator  i = d.begin(); i!=d.end(); i++)

         cout << *i << " ";

     cout << endl;

 

 

     double x[] = {3.4,6.7,111111111111 };

     double y[] = {3.4,6.7,111111111112 };

     vector<double> vx(x, x+4);

     vector<double> vy(y, y+4);

 

     if(equal(vx.begin(),vx.end(), vy.begin (), nastan_lika))

         cout << "nästan lika";

     else

         cout << "inte lika";

     cout << endl;

 

     //övriga operationer av funktionsobjekt

     for_each(vx.begin (), vx.end(), skriv);

     cout << endl;

 

     //transform

     vector<int> v2;

     v2.assign(v.begin(),v.end());

     cout << endl;

 

     transform(v.begin (), v.end(), v2.begin(), transformera);

     for_each(v.begin (), v.end(), skriv);

     cout << endl;

     for_each(v2.begin (), v2.end(), skriv);

     

    }

 

 

//funktionsobjekt

 

 

#include <iostream>

#include <vector>

#include "iodos.h"

#include <list>

#include <deque>

#include <iterator>

#include <algorithm>

 

using namespace std;

 

class Summerare{

    public:

    //konstruktor

    Summerare(double init=0) : sum(init){}

    //funktionsoperator

    double operator() (double x)

        { return sum += x;}

    private:

        double sum;

        };

 

void skriv(double a)

    {

    cout << a << " ";

    }

 

void main(){

     dos_console();

     

 

     vector<double>v ;

     vector<double>v2 ;

     for(int i=1;i<13;i++)

         {

         v.push_back(i);

         v2.push_back(i);

         }

     transform(v2.begin (), v2.end(),v.begin (), Summerare());

  

       for_each(v.begin (), v.end(), skriv);

      cout << endl;

 

      fill(v.begin(),v.end (),1); //fyller vektorn med ettor

      //här ändrar vi i samma datasamling som vi läser från

      transform(v.begin(),v.end(),v.begin (), Summerare());

 

      for_each(v.begin (), v.end(), skriv);

      cout << endl;

   

     

    }

 

Användning av fördefinierade funktionsobjekt

#include <functional>

I denna fil finns klasser för olika funktioner som plus, minus, multiplies, divides och negate.

Typen plus kan deklareras som:

plus<double> p;

Eftersom plus funktionen är en mall (template) skall man ange klasstyp. Man kan anropa den som en vanlig funktion   cout << p(4,5) << endl;  Skriver 9

 

Fördefinierade funktionsobjekt

Fördefinierade funktionsobjekt finns i filen <functional>

Ett temporärt fördefinierat funktionsobjekt skapas med ett uttryck på formen

operator<typ>()

där typ är typen för elementen i dne aktuella datasamlingen

operation kan vara någon av följande (a och b betecknar parametrarna vid ett anrop av funktionsobjektet)

plus                                      ger funktionsobjekt som returnerar             a+b

minus                                   ger funktionsobjekt som returnerar             a-b

multiplies                              ger funktionsobjekt som returnerar             a*b

divides                                 ger funktionsobjekt som returnerar             a/b

modulus                               ger funktionsobjekt som returnerar             a%b

negate                                  ger funktionsobjekt som returnerar  -a    negerar (negativt)

equal_to                               ger funktionsobjekt som returnerar             a==b

not_equal_to ger funktionsobjekt som returnerar                                   a!=b

greater                                 ger funktionsobjekt som returnerar             a>b

less                                      ger funktionsobjekt som returnerar             a<b

less_equal                            ger funktionsobjekt som returnerar             a<=b

greater_equal                       ger funktionsobjekt som returnerar             a>=b

logical_and                           ger funktionsobjekt som returnerar             a&&b

logical_or                             ger funktionsobjekt som returnerar             a| |b

logical_not                           ger funktionsobjekt som returnerar             ! a

 

 

 

 

Adapterfunktioner

Har funktionsobjekt som parametrar. Ger annat funktionsobjekt som resultat. (Här betecknar f1 och f2 funktionsobjekt med en respektive två parametrar och x ett värde).

bind1st(f2,x)                        gör om f2 till ett funktionsobjekt med en parameter. Den första parametern är  bunden till värdet  x.

bind2nd(f2,x)                       gör om f2 till funktionsobjekt med en parameter. Den andra parametrn är bunden till x.

not1(f1)                               ger ett funktionsobjekt som vid anrop returnerar det negerade värdet av ett anrop av f1

not2(f2)                               ger ett funktionsobjekt som vid anrop returnerar det negerade värdet av ett anrop av f2

ptr_fun(f)                             ger ett funktionsobjekt som vid anrop anropar funktionen f

 

 

Standardklassen list

l.reverse()                            vänder på listan

l.remove(e)                          tar bort alla förekomster av e i listan

l.remove(funk)                      tar bort alla element som uppfyller villkoret funk (är ett funktionsobjekt)

l.unique()                              tar bort dubletter i listan

l.sort()                                  sorterar listan

l.sort(funkobj)                      sorterar efter funktiionsobjektet

l.merge(l2)                           slår samman två listor listorna måste vara sorterade innan merge utförs

l.merge(l2,funkobj)               sorterar in listan – funkobj anger hur

l1.splice(p, l2)                      skjuter elementen i listan l2 i listan l före platsen p

l1.splice(p, l2,i)                    skjuter elementen i listan l2 i listan l före platsen p. Elementet tas bort ur l2. p och i är iteratorer

l1.splice(p, l2,i,j)                  skjuter elementen intervallet [i,j] i listan l2 före platsen p ilistan l. Elementen tas bort ur l2. p, i, j är iteratorer

 

 

 

 

UML

Analys 1

OOP med C++

Objektorienterad analys, vad?

Objektorienterad analys, hur finna klasser och deras egenskaper?

Objektorienterad analys, hur finna relationer?

 

Analys 2

OOP med C++

Associationer och aggregat

Associationer är fasta samband mellan klasser.

Leta efter verbfraser som t.ex. äger, arbetar hos, har som anställd, innehar, etc.

 

 

(eng. qualified)

Analys 3

OOP med C++

Hur bestämmer man vad som ska vara klasser?

 

 

OOP med C++

Vad är OOP?

 

Analys (vad skall göras?)

Design (hur ska det göras?)

Implementation

OOP med C++

Varför OOP?

 

OOP med C++

OOP vs. procedurorienterat

 

status (data)

uppförande (metoder)

identitet

OOP med C++

OOP vs. procedurorienterat, metodik

 

·         specifikation

·         analys

·         design

·         implementering

o        varje steg kräver att föregående steg avslutat

o        olika notation i olika steg

o        svårt att ändra i föregående steg

samma notation i analys och design

notationen blir ett effektivt kommunkationsmedel

OOP med C++

OOP vs. procedurorienterat, ramverk

 

o                               _______________

o                              |  Huvudprogram |  <---- Användarens kod

o                              |_______________|  

o                                  |   |   |

o                                  |   |   |

o                                  x   x   x      <---- Bibliotekskod

o                      

o                               _______________

o                              |  Framework    |  <---- Bibliotekskod

o                              |_______________|  

o                                  |   |   |

o                                  |   |   |

o                                  x   x   x      <---- Användarens kod

o                      

OOP med C++

UML-vyer (views)

 

 

 

 

OOP med C++

UML-byggstenar

 

 

2.                                    Strukturer (substantiv)

3.                                    Beteenden (dynamiska saker, verb)

4.                                    Grupperingar (organisatoriska saker)

5.                                    Noteringar (annotional things, förklaringar)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Att starta ett program med argument till main()

 

Det finns två sätt… Båda involverar Toolsarkivmenyn.

 

Om du går på ToolsCostumize och klickar på fliken Tools. Vi skapar en möjlighet att köra programmet härifrån och på så sätt kunna skicka argument…

Om du drar ner rullningslisten längst ner och klickar i det som ser ut som en tomruta får du möjlighet att skriva ett namn… t.ex. MedArgument

Klicka enter

 

I rutan efter Command söker du reda på din exe fil…  Du kan söka dig fram om du klickar på knappen med …

 

Sen har du två alternativ.

Antingen klickar du i ”Prompt for arguments”, då får du en ruta som frågar efter ditt argument när du kör

Eller så skriver du sökvägen till filen i Arguments…

 

När du sen ska köra ditt program så kör du det via Tools och väljer MedArgument