Thay đổi các file C++

Một phần của tài liệu Omnet và các ứng dụng (Trang 72 - 75)

5. MODULE ĐƠN GIẢN

6.2.6. Thay đổi các file C++

Mẫu Generation Gap

Đôi khi bạn cần các đoạn mã tự sinh ra có thể thực hiện được nhiều hơn hoặc khác đi so với những gì mà trình biên dịch tạo thành. Lấy ví dụ, khi đặt một trường số nguyên có tên là payloadLength, có thể bạn sẽ cần chỉnh sửa chiều dài của gói tin. Tuy nhiên đoạn mã tự sinh chỉ chứa hàm setPayloadLength(), điều này không thích hợp để đáp ứng yêu cầu đặt ra.

void FooPacket::setPayloadLength(int payloadLength) {

this->payloadLength = payloadLength; }

Để thoả mãn yêu cầu, hàm setPayloadLength() nên có dạng như sau: void FooPacket::setPayloadLength(int payloadLength)

{

int diff = payloadLength - this->payloadLength; this->payloadLength = payloadLength;

setLength(length() + diff); }

Bình thường, nhược điểm lớn nhất của việc sinh mã tự động là sự khó khăn khi thoả mã các yêu cầu của người sử dụng. Việc chỉnh sửa bằng tay lại các file tự động này là

{ properties: customize = true; fields: int payloadLength; };

Thuộc tính customize cho phép sử dụng mẫu Generation Gap.

Với đoạn khai báo trên, trình biên dịch message sẽ tạo ra lớp FooPacket_Base chứ không phải là lớp FooPacket như bình thường. Khi đó để thay đổi các hàm bạn sẽ phải tạo một lớp con từ lớp FooPacket_Base, ta gọi là lớp FooPacket.

class FooPacket_Base : public cMessage {

protected: int src;

// make constructors protected to avoid instantiation FooPacket_Base(const char *name=NULL); FooPacket_Base(const FooPacket_Base& other); public:

...

virtual int getSrc() const; virtual void setSrc(int src); };

Tuy vậy cũng không có nhiều hàm có thể được viết lại trong lớp FooPacket (có nhiều hàm không cho phép viết lại như các hàm khởi tạo do tính chất của quan hệ kế thừa): class FooPacket : public FooPacket_Base

{ public:

FooPacket(const char *name=NULL): FooPacket_Base(name){} FooPacket(const FooPacket& other): FooPacket_Base(other){}

FooPacket& operator=(const FooPacket& other) {

FooPacket_Base::operator=(other); return *this;

}

virtual cObject *dup() {

return new FooPacket(*this); }

};

Register_Class(FooPacket);

Quay trở về với ví dụ về thay đổi chiều dài gói tin, ta có thể viết đoạn mã như sau: class FooPacket : public FooPacket_Base

{

// here come the mandatory methods: constructor, // copy contructor, operator=(), dup()

// ...

virtual void setPayloadLength(int newlength); }

void FooPacket::setPayloadLength(int newlength) {

// adjust message length

setLength(length()-getPayloadLength()+newlength); // set the new length

FooPacket_Base::setPayloadLength(newlength); }

Trường trừu tượng

Mục đích của trường trừu tượng là cho phép người sử dụng có thể viết chồng lại cách thức giá trị của trường được lưu trữ bên trong lớp. Bạn có thể khai báo bất kỳ trường nào là trường trừu tượng với cú pháp sau:

message FooPacket {

properties: customize = true; fields:

Một phần của tài liệu Omnet và các ứng dụng (Trang 72 - 75)