2011-12-17 6 views
19

Tôi có một lớp không có hàm tạo mặc định hoặc toán tử gán để nó được khai báo và khởi tạo trong câu lệnh if/else tùy thuộc vào kết quả của hàm khác. Nhưng sau đó nó nói rằng nó nằm ngoài phạm vi mặc dù cả hai tuyến của điều kiện sẽ tạo ra một thể hiện.Phạm vi của các biến trong câu lệnh

Hãy xem xét ví dụ sau (thực hiện với int chỉ để minh họa cho điểm):

#include <iostream> 

int main() 
{ 
    if(1) { 
    int i = 5; 
    } else { 
    int i = 0; 
    } 

    std::cout << i << std::endl; 
    return 0; 
} 

Đừng biến khai báo trong một đi có điều kiện ra khỏi phạm vi ở phần cuối của các điều kiện? Cách chính xác để xử lý tình huống mà không có hàm tạo mặc định là gì nhưng các đối số cho hàm tạo phụ thuộc vào một số điều kiện nhất định?

Sửa

Trong ánh sáng của những câu trả lời được đưa ra, tình hình phức tạp hơn như vậy có lẽ phương pháp này sẽ phải thay đổi. Có một lớp cơ sở trừu tượng A và hai lớp B và C có nguồn gốc từ A. Làm thế nào sẽ như thế này:

if(condition) { 
    B obj(args); 
} else { 
    C obj(args); 
} 

thay đổi cách tiếp cận? Vì A là trừu tượng, tôi không thể chỉ khai báo A* obj và tạo kiểu thích hợp với new.

+0

Kế thừa của bạn là ảo hay tĩnh? – Dani

+0

Ảo, tôi nghĩ vậy. 'class A' có một hàm ảo, nếu đó là ý của bạn (C++ không phải là phù hợp mạnh mẽ của tôi, tôi làm việc chủ yếu ở Fortran) – tpg2114

+0

Bạn thực sự có thể khai báo một con trỏ tới một lớp trừu tượng - tôi đã chỉnh sửa câu trả lời của mình. –

Trả lời

16

"Các biến được khai báo trong một điều kiện có nằm ngoài phạm vi kết thúc của điều kiện không?"

- phạm vi của một biến cục bộ chỉ nằm trong dấu ngoặc kèm theo:

{ 
    int x; //scope begins 

    //... 
}//scope ends 
//x is not available here 

Trong trường hợp của bạn, nói rằng bạn có class A.

Nếu bạn đang phải đối phó với con trỏ:

A a(condition ? 1 : 2); 

hoặc nếu bạn đang sử dụng một nguyên mẫu nhà xây dựng khác nhau:

A a = condition ? A(1) : A(2,3); 

Nếu bạn đang tạo các trường hợp trên heap:

A* instance = NULL; 
if (condition = true) 
{ 
    instance = new A(1); 
} 
else 
{ 
    instance = new A(2); 
} 

hoặc bạn có thể sử dụng toán tử bậc ba:

//if condition is true, call A(1), otherwise A(2) 
A* instance = new A(condition ? 1 : 2); 

EDIT:

Có bạn có thể:

A* x = NULL; //pointer to abstract class - it works 
if (condition) 
    x = new B(); 
else 
    x = new C(); 

EDIT:

Có vẻ như những gì bạn đang tìm kiếm các mô hình nhà máy là (nhìn nó lên):

class A; //abstract 
class B : public A; 
class C : public A; 

class AFactory 
{ 
public: 
    A* create(int x) 
    { 
     if (x == 0) 
      return new B; 
     if (x == 1) 
      return new C; 
     return NULL; 
    } 
}; 
+0

Bộ nhớ có được cấp phát lại trong trường hợp này không ?? Sau khi phạm vi biến kết thúc sau dấu ngoặc {} kèm theo. – kaushalpranav

4

Làm biến tuyên bố trong một điều kiện đi ra khỏi phạm vi vào cuối điều kiện?

Có.

cách chính xác để xử lý các tình huống mà không có constructor mặc định nhưng các đối số cho các nhà xây dựng là gì phụ thuộc vào điều kiện nhất định?

Viết hàm trả về giá trị mà bạn sao chép.

T foo() 
{ 
    if(condition) 
     return T(x); 
    return T(y); 
} 

void bar() 
{ 
    T i(foo()); 
} 

Edit:

Từ A là trừu tượng, tôi có thể không chỉ cần khai báo A * obj và tạo kiểu phù hợp với mới.

Ý của bạn là gì? Đó chính là cách hoạt động của tính năng nhập động. Ngoại trừ tôi sẽ không sử dụng một con trỏ thô, tôi sẽ sử dụng một unique_ptr.

std::unique_ptr<A> obj; 
if(condition) { 
    obj = std::unique_ptr<A>(new B(args)); 
} else { 
    obj = std::unique_ptr<A>(new C(args)); 
} 
+0

Câu trả lời này mâu thuẫn với câu trả lời đầu tiên? (về việc liệu các biến được khai báo trong một điều kiện sẽ không nằm trong phạm vi kết thúc của điều kiện) – LazerSharks

+1

@Gnuey: Không. Tôi không chắc chính xác câu hỏi nào mà Luchian trả lời là "Không". Có lẽ anh ta chỉ bị nhầm lẫn giữa thời gian anh ta đọc câu hỏi và thời gian anh ấy viết câu trả lời. Nhưng tuyên bố đầy đủ, cũng như đoạn mã nhận xét theo sau, rõ ràng đồng ý với câu trả lời của tôi. –

0

Có nó sẽ nằm ngoài phạm vi nếu được khai báo trong vòng điều kiện, vòng lặp ... Loại biến có thay đổi tùy theo điều kiện không?

+0

Vì vậy, có cả hai trường hợp. Đôi khi nó là cùng một loại bất kể điều kiện, đôi khi nó là một loại khác nhau tùy thuộc vào điều kiện. Các cách tiếp cận sẽ thay đổi như thế nào cho hai tình huống? – tpg2114

+0

@ tpg2114 bạn đã đọc câu trả lời của tôi chưa? –

+0

Tôi có. Tôi thấy nó đề cập đến trường hợp đầu tiên (cùng loại). Làm cách nào để giải quyết các khả năng của các loại khác nhau được khai báo dựa trên điều kiện? – tpg2114

0

thay thế của bạn sẽ được gợi ý:

MyObject *obj; 
if(cond1) 
{ 
    obj = new MyObject(1, 2, 3); 
} 
else 
{ 
    obj = new MyObject(4, 5); 
} 

Hãy nhớ để xóa nó khi bạn đang thực hiện với nó, hoặc sử dụng một con trỏ thông minh.

+0

Bạn ** có thể ** sử dụng con trỏ, nhưng bạn không phải làm như vậy. –