編程|面向過程的函數調用與面向對象的消息傳遞(方法調用)
1 面向過程的函數調用
面向過程的程序以函數為核心,函數的使用一般包括函數聲明、函數定義、函數調用。
函數調用,也就是函數聲明和定義后的實際使用,可以作為表達式的一部分或函數實參(有返回值時),也可以作為單獨的一條語句(無返回值時)。
以下是同一個文件中函數調用的一個實例:
#include<iostream>
using namespace std;
long f1(int p);
long f2(int q);
long f1(int p)
{
int k;
long r;
k=p*p;
r=f2(k);
return r;
}
long f2(int q)
{
long c=1;
int i;
for(i=1;i<=q;i++)
Advertisements
c=c*i;
return c;
}
int main()
{
int i;
long s=24;
//for (i=2;i<4;i++)
i = 2;
s=s+f1(i);
printf("\ns=%ld\n",s);
system("pause");
return 0;
}
運行結果:
s=48
如果要調用外部函數(另一個cpp文件中),則不能在函數前面添加static限定詞,static表明函數為內部函數,只能在本文件中被其他函數調用。如果在函數前面聲明extern,則表面是外部函數,可以被其它cpp文件調用,C語言規定,如果在定義函數時省略extern,則隱含為外部函數。
當然,一個cpp文件調用另一個cpp文件(假設是A.cpp)中定義的外部函數時,需要先包含A.cpp的頭文件A.h。
Advertisements
A.h
#pragma once
static int add(int a, int b);//內部函數
extern int mul(int a, int b);//外部函數
A.cpp
#include <iostream>
using namespace std;
#include "A.h"
int add(int a, int b)
{
return a + b;
}
int mul(int a, int b)
{
return a * b;
}
main.cpp
#include<iostream>
using namespace std;
#include <stdio.h>
#include "A.h"
int main()
{
//printf("%d\n", add(4, 5));//在此處調用會編譯不通過
//因為add函數是內部函數,只能在文件內被調用
printf("%d\n", mul(4, 5));
system("pause");
return 0;
}
運行結果
20
2 一個類調用另一個類的方法
有時候,兩個類之間並沒有繼承的關係,但是其中一個類需要引用另一個類中的成員變數或者成員函數。怎樣辦到呢?
A.h
class A
{
public:
A();
~A();
public:
int Anum;
int Aadd();
};
B.h
class B
{
public:
B();
~B();
public:
int Bnum;
int x;
int Badd();
};
現在需要在類A的成員函數中調用類B的成員變數和成員函數,那麼只需要在類A的.cpp文件中包含類B的頭文件B.h。
A.cpp
#include <iostream>
using namespace std;
#include "A.h"
#include "B.h" //包含類B的頭文件
A::A()
{
Anum = 6;//初始化
}
A::~A()
{
}
int A::Aadd()
{
B BB;//實例化一個對象
BB.x = 5;//給對象中的一個成員變數賦值
int result;
result = Anum - BB.x + BB.Bnum + BB.Badd();//調用BB中的成員
//result = 6-5+3+9 = 13
return result;
}
B.cpp
#include "B.h"
#include <iostream>
using namespace std;
B::B()
{
Bnum=3;
}
B::~B()
{
}
int B::Badd()
{
int result;
result = Bnum * 3;
return result;
}
main.cpp
#include "A.h"
#include "B.h"
#include<iostream>
using namespace std;
int main()
{
A AA;
int result = AA.Aadd();
cout << result << endl;
system("pause");
return 0;
}
運行結果:
13
3 兩個類相互調用彼此的方法
兩個類A和B實現互相調用彼此的方法,如果採用彼此包含對方頭文件的方式會出現循環引用,可以採用了類的前置聲明的方式。
3.1 class A採用前置聲明的方式聲明class B;
3.2 在Class B的頭文件中包含class A 的頭文件;
3.3 在class A中只能聲明class B類型的指針或者引用;
具體代碼如下:
A.h:
#pragma once
class B;
class A
{
public:
A();
A(class B* pB);
~A();
public:
void displayA();
void invokeClassBInClassA();
private:
class B *mB;
};
A.cpp
#include "A.h"
#include "B.h"
#include <iostream>
usingnamespace std;
A::A()
{
}
A::A(B * pB)
{
mB = pB;
}
A::~A()
{
}
void A::displayA()
{
cout << "this is A" << endl;
}
void A::invokeClassBInClassA()
{
cout << "class A invoke class B starts>>" << endl;
mB->displayB();
}
B.h
#pragma once
#include "A.h"
class B
{
public:
B();
~B();
public:
void displayB();
void invokeClassAInClassB();
private:
class A * mA;
};
B.cpp
#include "B.h"
#include <iostream>
usingnamespace std;
B::B()
{
mA = new A();
}
B::~B()
{
}
void B::displayB()
{
cout << "this is the B" << endl;
}
void B::invokeClassAInClassB()
{
cout << "class B invoke class A starts >>" << endl;
mA->displayA();
}
main.cpp
#include <iostream>
#include "A.h"
#include "B.h"
usingnamespace std;
int main()
{
cout << "----------main starts---------------" << endl;
class B* pB = new B();
class A* pA = new A(pB);
pA->displayA();
pA->invokeClassBInClassA();
cout << "----------separate----------------" << endl;
pB->displayB();
pB->invokeClassAInClassB();
cout << "----------main ends----------------" << endl;
return 0;
}
運行結果:
----------main starts---------------
this is A
class A invoke class B starts>>
this is the B
----------separate----------------
this is the B
class B invoke class A starts >>
this is A
----------main ends----------------