第5章 Object Interactive

local variable

Local variables are deiined inside a method,have a scope limited to the metnod to which they belong.

int TicketMachine::refundBalance(){
    int amountToRefund;//本地变量
    amountToRefund = balance;
    balance = 0;
    return amountToRefund;
}

A local variable of the same name as a field will prevent the  field being accessed from within a method.

Fields, parameters, local variables

local

glocal

member

lifestyle生存期

{ }

全局

对象创建或销毁

scope作用域

{ }

全局

• All three kinds of variable are able to store a value that is appropriate to their defined type.

• Fields are defined outside constructors and methods

• Fields are used to store data that persists throughout the  life of an object. As such, they maintain the current state of  an object. They have a lifetime that lasts as long as their  object lasts. 

• Fields have class scope: their accessibility extends  throughout the whole class, and so they can be used within  any of the constructors or methods of the class in which  they are defined.

• As long as they are defined as private, fields cannot be accessed from anywhere outside their defining class. 

• Formal parameters and local variables persist only for the  period that a constructor or method executes. Their  lifetime is only as long as a single call, so their values are  lost between calls. As such, they act as temporary rather  than permanent storage locations. 

• Formal parameters are defined in the header of a  constructor or method. They receive their values from  outside, being initialized by the actual parameter values that  form part of the constructor or method call.

• Formal parameters have a scope that is limited to their defining constructor or method. 

• Local variables are defined inside the body of a constructor  or method. They can be initialized and used only within the  body of their defining constructor or method. 

• Local variables must be initialized before they are used in an  expression – they are not given a default value. 

• Local variables have a scope that is limited to the block in  which they are defined. They are not accessible from  anywhere outside that block.

C++ access control

• The members of a class can be cataloged, marked  as: 

– public 

– private 

– protected

public 

• public means all member declarations that follow are available to everyone.

• Example: Public.cpp

Struct A{
  //未声明public,说明都是public
  int i;
  char j;
  float t;
  void func();
};
void A::func(){}

struct B{
public:
  int i;
  char j;
  float t;
private:
  void func();
};
void B::func(){}

int main(){
  A a;
  B b;
  a.i = b.i = 1;
  a.j = b.j = 'c';
  a.t = b.t = 3.14159;
  a.func();
  b.func();
}

private

• The private keyword means that no one can access that member except inside function members of that type. 

• Example: Private.cpp

struct B{
public:
  int i;
  void func();
private:
  char j;
  float t;
};
void B::func(){
  i = 0;
  j = '0';
  t = 0.8;
}
int main(){
  B b;
  b.i = 1;//ok,public
  b.j = '1';//Illegal,private
  b.t = 1.0;//Illegal,private
}

修改

struct B{
public:
  int i;
  void func();
void ff(B* p);
private:
  char j;
  float t;
};
void B::func(){
  i = 0;
  j = '0';
  t = 0.8;
}
void B:: ff(B* p){
  p -> j = 'A';
}
int main(){
  B b;
  B bb;
  b.ff(&bb);//虽然bb的j是private,但可以用b的ff函数访问
}

private的边界是类,不是对象

Friends友元

• to explicitly grant access to a function that isn’t a  member of the structure 

• The class itself controls which code has access to  its members. 

• Can declare a global function as a friend, as well  as a member function of another class, or even an  entire class, as a friend. 

• Example: Friend.cpp

struct X;

struct Y{
  void f(x*);
};
strcut X{
private:
  int i;
public:
  void initialize();
  friend void g(X*, int);//全局友元
  friend void Y::f(X*);//结构体函数友元
  friend strcut Z;//整个结构体是友元
  friend void h();
};

void X::initialize(){
  i = 0;
}
void g(X* x, int i){
  x -> i = 47;
}
void Y::f(X* x){
  x -> i = 47;
}

class vs. struct

• class defaults to private

• struct defaults to public. 

• Example: Class.cpp

class B{
  int i, j, k;//不在public里,说明是private
public:
  int f();
  void g();
};

对类来说,没有声明访问属性,默认是private;而结构体默认的访问属性是public

Initialization

Member Init 

• Directly initialize a member 

• benefit: for all ctors

• Only C++11 works

Initializer list

class Point {
private:
 const float x, y;//const表示成员变量一旦赋值就不能被修改
 Point(float xa = 0.0, float ya = 0.0)
   : y(ya), x(xa) {}
};
/*:{} —— 初始化列表,只有构造函数能使用,会在构造函数执行之前调用y,x的构造函数,将其初始化。
初始化顺序是按照定义的顺序,不是初始化列表的顺序
*/

• Can initialize any type of data

– pseudo-constructor calls for built-ins

– No need to perform assignment within body of ctor

• Order of initialization is order of declaration

– Not the order in the list!

– Destroyed in the reverse order.

#include <iostream>
#include <iomanip>
using namespace std;

class Point{
private:
  const int x, y;
public:
  Point(int ax, int ay);
};
Point::Point(int ax, int ay){
  x = ax;
  y = ay
}
int main(){
  Point p(1, 2);
}
/*
报错,因为用了const,不能被赋值,只有在初始化的时候指定值,如const int a = 1;
*/

Initialization vs. assignment初始化和赋值

Student::Student(string s):name(s) {} 

initialization

before constructor

Student::Student(string s) {name=s;} 

assignment

inside constructor

string must have a default constructor

class Point{
private:
  const int x, y;
public:
  Point(int ax, int ay);
};
Point::Point(int ax, int ay):x{ax}, y{ay}{
 
}

class Rectangle{
private:
  Point p1, p2;
public:
  Rectangle(int x1, int y1, int x2, int y2);
}

Rectangle::Rectangle(int x1, int y1, int x2, int y2){
  
}
//会报错,p1, p2缺少默认构造函数
int main(){
  Point p(1, 2);
}

修改

class Point{
private:
  const int x, y;
public:
  Point(int ax, int ay);
  Point():x(0), y(0){cout << 'def' << endl;}
};
Point::Point(int ax, int ay):x{ax}, y{ay}{
 cout << "Point" << endl;
}

class Rectangle{
private:
  Point p1, p2;
public:
  Rectangle(int x1, int y1, int x2, int y2);
}

Rectangle::Rectangle(int x1, int y1, int x2, int y2){
  
}
//会报错,p1, p2缺少默认构造函数
int main(){
  Point p(1, 2);
  Rectangle(1,2,3,4);
}
/*
输出:
Point
def
def
*/

Function overloading 函数重载

• Same functions with different arguments list.

void print(char * str, int width); // #1 

void print(double d, int width); // #2 

void print(long l, int width); // #3 

void print(int i, int width); // #4 

void print(char *str); // #5 

print("Pancakes", 15);  1

print("Syrup");  5

print(1999.0, 10);2

print(1999, 12); 4

print(1999L, 15); 3

Example: leftover.cpp

unsigned long left(unsigned long num, unsigned cl);
char* left(char* str, int n = 1);

int main(){
  using namespace std;
  char* trip = "Ha";
  unsigned long n = 12345678;
  int i;
  char* temp;

  for(i = 1; i < 10; i++){
    cout << left(n, i) << endl;//第一个
    temp = left(trip, i);//第二个
    cout << temp << endl;
    delete [] temp;
  }
  return 0
}

Overload and auto-cast

void f(short i);

void f(double d);

f(‘a’); //cahr类型

f(2); //int

f(2L); //long

f(3.2);//用double

前面三种都会报错

Default arguments

• A default argument is a value given in the  declaration that the compiler automatically inserts if you don’t provide a value in the function call. 

Stash(int size, int initQuantity = 0);

调用时可以只给一个值,会给size

• To define a function with an argument list, defaults  must be added from right to left. 

int harpo(int n, int m = 4, int j = 5); 

int chico(int n, int m = 6, int j);//illeagle 如果给两个值,无法分辨第二个值给m还是j

int groucho(int k = 1, int m = 2, int n = 3); 

beeps = harpo(2); 

beeps = harpo(1,8); 

beeps = harpo(8,7,6); 

Example: left.cpp

#include <iostream>
const int ArSize = B0;
char* left(char* str, int n = 1);
int main(){
  using namespace std;
  char sample(ArSize);
  cout << "Enter a string:\n";
  cin.get(sample.ArSize);
  char* ps = left(sample, 4);//n等于4
  cout << ps << endl;
  delete [] ps;
  ps = left(sample);//n为默认值1
  cout << ps << endl;
  delete[] ps;
  return 0;
}

Pitfall of default arguments

The default arguments are declared in its prototype(原型),not defined in its function head

Can not put default arguments in definition     May be changed by ill-formed prototype

Can not put default arguments in definition

void f(int i, int j = 10);
int main(){
  f(1, 2);
  f(1);
}
void f(int i, int j = 10){//声明和定分开时,默认参数不能写在定义的地方
  cout << j << endl;
}
void f(int i, int j = 10){//声明和定义合并时,默认参数可以写在定义的地方
  cout << j << endl;
}
int main(){
  f(1, 2);
  f(1);
}
//报错
void f(int i, int j = 10);
void f(int i, int j = 10){
  cout << j << endl;
}
int main(){
  f(1, 2);
  f(1);
}

May be changed by ill-formed prototype

//会报错,因为有默认参数,不构成重载当只传入一个车参数时,会混淆
void f(int i, int j = 100);
void f(int k);

Overhead for a function call 函数调用开销

• the processing time required by a device prior to the execution of a command 

• Push parameters 

• Push return address 

• Prepare return values 

• Pop all pushed

Inline function 内联函数

• An inline function is expanded in place, like a preprocessor macro, so the overhead of the function call is eliminated.

int f(int i){
  return i * 2;
}

main(){
  int a = 4;
  int b = f(a);
}

inline int f(int i){
  return i * 2;
}

main(){
  int a = 4;
  int b = f(a);
}

使用incline,不会编译产生f函数,调用函数时会把f的代码嵌入到调用的位置

inline int plusOne(int x);

inline int plusOne(int x) {return ++x; };

• Repeat inline keyword at declaration and 

definition. 

• An inline function definition may not generate any  code in .obj file.

.h

a.cpp

编译

解释

无inline

无incline

正确

正常

incilne

incline

warning,link

a.o没有函数,链接函数发现main.o需要函数,但没在a.o中找到,连接错误

incline

无incline

warning

main.o调用a.o的函数

incline函数的body不是definition,而是decalration

如果要用incline函数,需要把整个函数体放到头文件,不能把声明放在头文件,定义放在.cpp

Inline functions in header file

• So you can put inline functions’ bodies in header  file. Then #include it where the function is needed. 

• Never be afraid of multi-definition of inline 

functions, since they have no body at all. 

• Definitions of inline functions are just declarations.

Tradeoff of inline functions

• Body of the called function is to be inserted into the  caller. 

• This may expand the code size  but deduces the overhead of calling time.  So it gains speed at the expenses of space. 

• In most cases, it is worth.  It is much better than macro in C. It checks the types of  the parameters.

与宏区别

宏没有类型检查,inline可以

#define f(a) (a)+(a)

main() {
  double a=4;
  printf(“%d”,f(a));
}

inline int f(int i) {
  return i*2;
}
main() {
  double a=4;
  printf(“%d”,f(a));
}

Inline may not in-line

• The compiler does not have to honor your request  to make a function inline. It might decide the  function is too large or notice that it calls itself  (recursion is not allowed or indeed possible for  inline functions), or the feature might not be  implemented for your particular compiler.

Inline inside classes

• Any function you define inside a class declaration  is automatically an inline. 

• Example: Inline.cpp

class Point{
  int i, j, k;
public:
  Point(){i = j = k = 0;}
  Poing(int li, int lj, int lk){i = li, j = lj, k = lk;}
  void print(string& msg = ""){
    if(msg.size() != 0){cout << msg << endl;}
    cout << "i =" << i << ","
         << "j =" << j << ","
         << "k =" << k << endl;
  }
};

body出现在类内的函数就是incline函数,不需要加incline关键字

Access functions 用来访问每个成员变量的值

class Cup{
  int color;
public:
  int getColor(){return color;}
  void setColor(int color){
    this -> color = color;
  }
};

• They are small functions that allow you to read or  change part of the state of an object – that is, an  internal variable or variables

Pit-fall of inline

• You can put the definition of an inline member 

function out of the class braces. 

• But the definition of the functions should be put  before where they may be called. 

• Example: NotInline.h, NotInline.cpp, NotInlineTest.cpp

Reducing clutter

• Member functions defined within classes use the  Latin in situ (in place) and maintains that all 

definitions should be placed outside the class to 

keep the interface clean. 

• Example: Noinsitu.cpp

class Rectangle{
  int width, height;
public:
  Rectangle(int w = 0, int h = 0);
  int getWidth() const;
  void setWidth(int w);
  int getHeight()const;
  void setHeight(int h)
};

inline Rectangle::Rectangle(int w, int h):width(w), height(h){}

inline int Rectangle::getWidth() const{
  return width;
}

类内成员函数声明时不是incline,但定义时指明inline

Inline or not?

• Inline: 

• Small functions, 2 or 3 lines 

• Frequently called functions, e.g. inside loops 

• Not inline? 

• Very large functions, more than 20 lines 

• Recursive functions 递归函数

• A lazy way 

• Make all your functions inline 

• Never make your functions inline

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值