Constructor, Overloading Operator và từ khóa const trong C++

Mình có vài câu hỏi về constructor, overload operator trong C++. Mong các bạn xác minh là mình hiểu đúng không. Những cái này mình ghi trong comment bên cạnh code nha.

Vấn đề 1: mình hiểu mấy cái này đúng không?

Vect() // cái này là default constructor
{};

Vect( const Vect &t) //constructor được gọi khi truyền vào 1 object Vect
{}

Vect &operator = (const Vect &tmp)// overload assignment operator
{}

~Vect() //destructor
{}

//cái bên dưới là constructor được gọi khi nhận tham số truyền vào kiểu primitive type

Vect( const float tx, const float ty, const float tz, const float tw )
{}

//overload cái + operator. Trả về một vector sau khi cộng. Cái này dùng để tạo một object mới nên return là Vect.

Vect operator + (const Vect &t) const
{
    return Vect(this->x + t.x, this->y + t.y, this->z + t.z, this->w + t.w);
}
//cũng là cộng vector nhưng là để update data trong Object Vector hiện tại. Vì chỉ update data trong object vector hiện tại nên return là *this;

Vect & operator += (const Vect4D &t)
{
	this->x += t.x;
	this->y += t.y;
	this->z += t.z;
	this->w += t.w;
	return *this;
}

Vấn đề thứ 2 là từ khóa const. Giả sử mình có 1 class mà data được set private và mình viết setter như sau:

float getA() const

float getA()

Hai cái trên khác nhau chỗ nào vậy? Theo mình biết thì khi mình viết const ở cuối function, những data của object sẽ không được thay đổi trong quá trình viết định nghĩa cho hàm. Ví dụ:

class abc {
private:
	int a;

public:
	float asb() const {
	a++;
	return a;
	}
};

Nếu làm như trên thì không được. Nó sẽ báo lỗi không cộng a lên 1 đơn vị được.

Nhưng bên trên là getter thôi thì tại sao phải có lúc phải const, lúc không.

Nếu mình chỉ viết hàm bình thường thì có nên viết const phía cuối hàm không?

Vấn đề cuối là overloading operator:

Vect operator + (const Vect &t) const

Vect & operator += (const Vect &t)

Sao 2 cái trên mình để ý là 1 cái dùng reference nhưng không có const phía sau, 1 cái có const nhưng không dùng reference. Nó khác nhau như thế nào vậy?

Hi Anh Nguyen.

  1. Về các định nghĩa bạn xem lại đặc tả ngôn ngữ.
  2. Về hàm const thì mình thấy nó sẽ yêu cầu các câu lệnh trong nó không làm thay đổi giá trị đối tượng và báo lỗi khi biên dịch, nói chung là tùy chọn viết code chặt chẽ thôi dùng cũng được không dùng cũng không sao.
#include <iostream>

class Test {
    public:
        Test(int);
        int getValue();
        void setValue(int);
        void testConst() const;
    private:
        int value;
};

int main(int argc, char** argv) {
    Test test(10);
    test.testConst();
}

Test::Test(int value) : value(value) {
//TODO
}

int Test::getValue() {
    return this->value;
}

void Test::setValue(int value) {
    this->value = value;
}

void Test::testConst() const {
    // std::cout << this->getValue() << std::endl; // Vì là hàm const nên mọi hàm trong nó cũng phải const. Lỗi biên dịch.
    std::cout << this->value << std::endl;
}

Vect( const Vect& t)
Vect& operator = (const Vect& t)

2 cái này là copy constructor và overload =
Chúng là 1 trong những khái niệm cơ bản và quan trọng của class và object trong C++. Bạn nên đọc thêm sách về phần này (deep vs shallow copy)


float getA() const

float getA()

Ví dụ bạn có

const A a;
a.getA() // complile đc với `getA() const` ko compile đc với `getA()`

const là 1 keyword quan trọng trong c++. Nên tìm hiểu kỹ về const .Tìm hiểu thêm về keyword mutable trong phần này.


Vect operator + (const Vect& t) const
Vect& operator += (const Vect & t)

2 cái này trong định nghĩa bạn cũng thấy rồi đó.
Cái overload đầu tiên trả về 1 vector khác, không modify các vector có trong hàm
Ví dụ:

Vect vectorA(0, 0, 0, 0);
Vect vectorB(0, 1, 0, 1);
vectorA + vectorB; //ko thay đổi giá trị của A và B
Vect vectorC;
vectorC = vectorA + vectorB //ko thay đổi giá trị của A và B

Nếu như cũng đoạn code ở trên

Vect operator + (const Vect& t) const
{
    this ->x + t.x; // lỗi compile. Check xem lỗi gì.
    return Vect(this->x + t.x, this->y + t.y, this->z + t.z, this->w + t.w);
}
Vect& operator += (const Vect& t) const // lỗi compile
{
    this->x += t.x;
    this->y += t.y;
    this->z += t.z;
    this->w += t.w;
    return *this;
}

Và như giải thích ở trên, cái này trả về 1 ref của Vect và thay giá trị trong nó nên không thể để const ở cuối đc.

1 Like

Cám ơn bạn. Kiến thức về C++ của mình không vững nên hỏi những cái như trên.

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?