• No results found

Programsystemkonstruktion med C++

N/A
N/A
Protected

Academic year: 2021

Share "Programsystemkonstruktion med C++"

Copied!
19
0
0

Loading.... (view fulltext now)

Full text

(1)

Daniel Aarno

bishop@kth.se

Programsystemkonstruktion med C++

Övning 3

(2)

Översikt övning 3

Virtuellt arv Strömmar Iteratorer

Effektiv C++

Tips

Tentatal

2

(3)

Virtuellt arv

3

Undvik att få dubbla medlemmar vid multipelt arv

class Animal  {

  private:

string name;

};

 

class Donkey : virtual public Animal 

};

class Horse : virtual public Animal  {

};

class Mule : public Donkey, public Horse 

  private:

    // inherits one name from Animal

};

(4)

Strömmar

4

Input/Output i C

int fprintf(FILE *stream, const char *format, ...);

int fscanf(FILE *stream, const char *format, ...);

int main() { char c;

FILE* fp = fopen(“/tmp/file.txt/”, “rb”);

while(fscanf(fp, “%c”, &c) == 1) printf(“%c”, c);

fclose(fp);

fprintf(stderr, “Nothing more in the file”);

fprintf(stdout, “Pi has the value: %.4f %s”,  M_PI, “\nSo there!\n”);

printf(“Press enter to exit:> “);

fflush(stdout);

scanf(“%*s”); //< Read a string and ignore it return 0;

}

(5)

Strömmar (cont'd)

5

Input/Output i C++

int main() { char c;

istream infile(“/tmp/file.txt/”, ios_base::binary);

while(infile.get(c)) { //< can not use infile >> c

cout << c; //  because it ignores binary mode }

cerr << “Nothing more in the file”;

cout << “Pi has the value: “ << precision(4) << 

M_PI << “\nSo there!” << endl;

cout << “Press enter to exit:> “;

cout.flush();

cin.ignore(); //< Read a string and ignore it return 0;

} //infile closed here

(6)

Strömmar (cont'd)

6

Formatering

width(int i);

precision(int i);

setf(fmtflags f);

fmtflags flags();

fmtflags:

left  //< pad after value right  //< pad before value

boolalpha //< symbolic representation of true/false scientific //< 3.141592e3

fixed //< 3141.592 ...

(7)

Strömmar (cont'd)

7

class A { public:

int i;

virtual ~A();

virtual void doStuff();

};

class B : public A { public:

int j;

void doStuff();

};

ostream& operator<<(ostream &o, const A &a) { o << a.i;

return o;

}

ostream& operator<<(ostream &o, const B &b) { o << b.i << ' ' << b.j;

return o;

}

(8)

Strömmar (cont'd)

8

int main() {

A a;

B b;

A &aRef = b; //< OK, a is public base of B cout << a << endl;

cout << b << endl;

cout << aRef << endl; //< Hmmm, what will happen here?

return 0;

}

(9)

Strömmar (cont'd)

9

class A { public:

int i;

virtual ~A();

virtual void doStuff();

virtual ostream& print(ostream &o) { o << i; return o;}

};

class B : public A { public:

int j;

void doStuff();

ostream& print(ostream &o) { o << i << j; return o; } };

ostream& operator<<(ostream &o, const A &a) {

return a.print(o);  //< Now all subclasses of A will print //correctly. using only one operator<<

//and virtual bindings in the class }

(10)

Iteratorer

10

template<typename T>

ostream& operator<<(ostream& os, const vector<T> &v) {

  string sep = "";

  ofstream *ofs = dynamic_cast<ofstream*>(&os);

  if(ofs != 0) {     os << v.size();

    sep = " ";

  }    

  for(typename vector<T>::const_iterator it = v.begin(); 

it != v.end(); ++it) {     os << sep << *it;

    sep = " ";

  }

  return os;

}

(11)

Iteratorer (cont'd)

11

template<typename T>

istream& operator>>(istream& is, vector<T> &outVec) {

  ifstream *ifs = dynamic_cast<ifstream*>(&is);

  if(ifs != 0)

    return ReadVec(*ifs, outVec);

  string line;

  getline(is, line);

  outVec.clear();

  istringstream iss(line);

  T val;

  while(iss >> val) {

    outVec.push_back(val);

  }

  return is;

}

(12)

Iteratorer (cont'd)

12

template<typename T>

istream& ReadVec(ifstream& is, vector<T> &outVec) {

  int nmemb;

  is >> nmemb;

  outVec.clear();

  istream_iterator<T> isi(is);

  copy(isi, istream_iterator<T>(), back_inserter(outVec));

  

  return is;

}

(13)

Iteratorer (cont'd)

13

template<typename T>

ostream& operator<<(ostream& os, const vector<T> &v) {

  ofstream *ofs = dynamic_cast<ofstream*>(&os);

  if(ofs != 0) {

    os << v.size() << ' ';

  }    

  copy(v.begin(), v.end(), ostream_iterator<T>(os, " "));

  return os;

}

(14)

Effektiv C++

14

Undvik temporära objekt

Använd initialiseringslista Undvik return-by-value

Var noggrann med iteratorer

Använd std-funktioner, algoritmer etc

Optimera där det hjäper

(15)

Effektiv C++ (cont'd)

15

Template <typename T> void foo(U &a, U &b) { cout << “foo()” << endl;

}

Template <typename T> void bar(const U &a, const U &b) { cout << “bar()” << endl;

}

int main () { int i = 2;

char c = 'a';

foo<int>(i,c); //< will not compile because temporary    //< objects may not be changed

bar<int>(i,c); //< compiles OK }

Temporära objekt

(16)

Effektiv C++ (cont'd)

16

struct Student { string name;

string addr;

};

string FindAddr(list<Student> l, string name { for(list<Student>::iterator i = l.begin();

i != l.end(); i++)  {

if(*i == name)

return i­>addr;

}

return “”;

}

Temporära objekt

Finn 5 “fel”

(17)

struct Student { string name;

string addr;

};

string FindAddr(list<Student> l, string name) { for(list<Student>::iterator i = l.begin();

i != l.end(); i++)  {

if(*i == name)

return i­>addr;

}

return “”;

}

Effektiv C++ (cont'd)

17 Temporära objekt

Ej const&

++i är snabbare

i->name

(18)

Effektiv C++ (cont'd)

18

struct Student { string name;

string addr;

};

const string& FindAddr(const list<Student> &l,  const string &name 

{

static const string dummy;

for(list<Student>::const_iterator i = l.begin();

i != l.end(); ++i)  {

if(i­>name == name) return i­>addr;

}

return dummy;

}

Temporära objekt

(19)

Effektiv C++ (cont'd)

19

class NameEq {

const string &m_name;

public:

NameEq(const std::string &nam) : m_name(nam) {}

bool operator()(const Student& s)  { return s.name == m_name; }

};

const string& FindAddr(const list<Student> &l,  const string &name 

{

static const string dummy;

list<Student>::const_iterator it = 

find_if(l.begin(), l.end(), NameEq(name));

return it != l.end() ? *it : dummy;

}

Temporära objekt

References

Related documents

• Skriv metoden bool move_event(const Date &amp; from, const Date &amp; to, std::string event) som kan flytta händelser i kalendern genom att först plocka ut och sedan lägga

BigNum används när man vill ha en kopia för sidoeffekternas skull (ovanligt) eller när datatypen är så liten att referen- sanrop ger onödigt arbete. const BigNum är faktiskt

Kompi- leringstiderna minskar eftersom beroendena minskar (ta t.ex. extremfallet med endast en .h-fil och en .cpp-fil där allt kompileras om vid varje ändring). Det blir lättare

en C++-klass best˚ ar av en deklaration och en definition deklaration vanligtvis i .h (.hh) och definition i .cpp (.cc) private ¨ ar f¨ orvalt f¨ or funktioner och variabler i

undvik enraders if-satser, anv¨ and alltid { och } undvik om m¨ ojligt n¨ astlade if/for satser skriv inte f¨ or l˚ anga funktioner, dela upp. versionshantera all kod med program

templates (models) used to write type independednt code inheritance is an alternative to shared behaviors. functions and classes parameterized on a

argv[0] är programmets namn (tex /usr/bin/zip eller zip) main() är en global funktion och således inte del av någon klass. main() behöver

Virtuella funktioner bestäms dynamiskt under exekvering baserat på objektets faktiska