2013-08-29 41 views
5

Tôi mới tham gia C++ và gần đây đã thực hiện nghiên cứu về lập trình hướng khách quan. Tôi muốn viết mô-đun đại số tuyến tính của mình xử lý các vectơ ba chiều và ma trận 3x3. Tôi đã cố gắng xác định một ma trận như một lớp bao gồm ba vectơ.Xây dựng một lớp học sử dụng một lớp khác C++

class vector { 
    public: 
    double n1, n2, n3; 
    vector (double a, double b, double c) { 
     n1 = a; n2 = b; n3 = c; 
     } 
    }; 

class matrix { 
    public: 
     vector m1, m2, m3; 
     matrix (vector a, vector b, vector c) { 
       m1 = a; m2 = b; m3 = c; 
       } 
     }; 

Tuy nhiên, tôi nhận được một lỗi biên dịch:

In constructor `matrix::matrix(vector, vector, vector)': 
no matching function for call to `vector::vector()' 

Tôi đoán rằng chương trình doesnt biết làm thế nào để xây dựng một ma trận bằng cách sử dụng lớp vector i xác định. Tuy nhiên tôi không hiểu tại sao. Nếu ai đó có thể giải thích, tôi sẽ rất biết ơn.

+1

Sử dụng danh sách initializer thay vì gán cho chúng trong cơ thể constructor. –

+0

có thể trùng lặp của [Cú pháp thành viên dấu hai chấm lạ này trong hàm tạo là gì?] (Http://stackoverflow.com/questions/1711990/what-is-this-weird-colon-member-syntax-in-the-constructor) –

+2

bạn có thể muốn đặt lớp vectơ của bạn bên trong một không gian tên để tránh nhầm lẫn với 'std :: vector'. Bởi vì khi tôi đọc lớp ma trận của bạn, tôi đã nghiêm túc nghĩ rằng bạn định sử dụng 'std :: vector', nhưng đó không phải là trường hợp. – hetepeperfan

Trả lời

6

Bạn cần phải khởi tạo m1,m2,m3 thành viên của bạn bằng danh sách initializer thành viên:

matrix (const vector& a, const vector& b, const vector& c) 
: m1(a),m2(b),m3(c) 

Lưu ý những điều sau:

  • Hình thức này có thể được sử dụng chỉ với nhà thầu.
  • Bạn phải (ít nhất, bằng pre-C++ 11) sử dụng biểu mẫu này để khởi tạo nonstatic const thành viên dữ liệu.
  • Bạn phải sử dụng biểu mẫu này để khởi tạo tài khoản tham chiếu thành viên dữ liệu.

Ngoài ra, lưu ý, có std::vector, bạn có thể đổi tên vectơ của riêng mình để hủy bỏ xung đột đặt tên và bạn nên vượt qua vector theo tham chiếu const.

1

Nó là cần thiết constructor mặc định của vector lớp, là không có tham số:

class vector { 
    public: 
    double n1, n2, n3; 
    vector() { // <- this one 
    n1 = 0; n2 = -1; // sample initializing code 
    }; 
    vector (double a, double b, double c) { 
     n1 = a; n2 = b; n3 = c; 
     } 
    }; 
4

Dưới đây là tại sao này đang xảy ra sai:

Xây dựng của một đối tượng xảy ra trong nhiều giai đoạn. Đối với lớp ma trận của bạn, trước tiên bạn cần phải xây dựng tất cả các đối tượng thành viên và chỉ sau đó thi hành phần thân của hàm tạo. Điều quan trọng cần nhận ra ở đây là trước khi cơ thể khởi tạo được nhập vào, tất cả các đối tượng thành viên (trong trường hợp của bạn là m1, m2m3) phải được xây dựng.

Vấn đề là trình biên dịch không thể tự xây dựng các thành viên vector: Nó chỉ biết một hàm tạo cho vector và một yêu cầu phải có ba double s để xây dựng mà nó không có. Bạn có thể cung cấp trình biên dịch với các đối số constructor bị thiếu đó cho vector bằng cách sử dụng cú pháp danh sách khởi tạo, như được đề xuất bởi câu trả lời của billz.

Điều này làm việc vì danh sách bộ khởi tạo được thực hiện trong giai đoạn khởi động thành viên của giai đoạn khởi động, xảy ra trước giai đoạn cơ thể của nhà xây dựng.

Cách khác, cung cấp hàm khởi tạo mặc định cho vector để trình biên dịch có thể tự động xây dựng thành viên ma trận mà không có thông tin bổ sung, như được gợi ý bằng câu trả lời của Zac.

0

Lý do tại sao bạn gặp lỗi này là:

  1. lớp vector của bạn không có constructor mặc định khi bạn đã xác định một constructor rõ ràng với các thông số.
  2. Thành viên dữ liệu của một đối tượng sẽ được khởi tạo trong khi xây dựng đối tượng nhưng trước khi mã trong hàm tạo được thực hiện.

Vì vậy, khi trình biên dịch muốn tạo đối tượng ma trận, trước tiên cần xây dựng/khởi tạo m1/m2/m3 cho các mã "{m1 = a; m2 = b; m3 = c;}" của hàm tạo ma trận. Tuy nhiên, lớp m1/m2/m3 không có hàm khởi tạo mặc định nào được gọi. Đây là lý do tại sao trình biên dịch báo cáo "Trong hàm tạo matrix::matrix(vector, vector, vector)': no matching function for call to vector :: vector() '"

Giải pháp là khởi tạo m1/m2/m3 thông qua danh sách khởi tạo thành viên. Điều này hoạt động vì:

  1. Trình biên dịch sẽ cung cấp "bản sao mặc định" (thực sự chỉ là bản sao bit cho trường hợp của bạn) khi nó không được xác định.
  2. "Nhà xây dựng bản sao mặc định" này có thể được gọi thông qua danh sách khởi tạo thành viên.
0

Hoặc với "đề nghị C++ 11" cách:

matrix (vector a, vector b, vector c) 
: m1(std::move(a)),m2(std::move(b)),m3(std::move(c)) { 
} 
Các vấn đề liên quan