هل من الممكن لخلق متجه من المؤشرات؟
-
03-07-2019 - |
سؤال
وأتساءل فقط، بسبب وجود مشكلة أنا على التوالي في، هل من الممكن لخلق متجه من المؤشرات؟ وإذا كان الأمر كذلك، كيف؟ فيما يتعلق على وجه التحديد باستخدام التكرارات و.begin () مع ذلك، أي: كيف أنتقل هذا متجه إلى متجه من المؤشرات:
class c
{
void virtual func();
};
class sc:public c
{
void func(){cout<<"using func";}
};
sc cobj;
vector<c>cvect
cvect.push_back(cobj);
vector<c>::iterator citer
for(citer=cvect.begin();citer<cvect.end();citer++)
{
citer->func();
}
المحلول 2
وvector <c> cvect
ليس متجه من المؤشرات. وهو متجه كائنات من نوع ج. تريد vector <c*> cvect
. وربما كنت ترغب:
cvect.push_back( new c );
وبعد ذلك، نظرا مكرر، كنت تريد شيئا مثل:
(*it)->func();
وبطبيعة الحال، فإنه من المحتمل جدا أنك لا تريد متجه من المؤشرات في المقام الأول ...
نصائح أخرى
وبالتأكيد.
vector<c*> cvect;
cvect.push_back(new sc);
vector<c*>::iterator citer;
for(citer=cvect.begin(); citer != cvect.end(); citer++) {
(*citer)->func();
}
وأمور يجب وضعها في الاعتبار:
وسوف تحتاج إلى تنظيف بعد نفسك إذا كنت تستخدم الذاكرة المخصصة حيوي كما فعلت في بلدي على سبيل المثال
ومنها مثلا:
for(...) { delete *i; }
وهذا يمكن أن تكون مبسطة باستخدام ناقلات من shared_ptr
s (مثل boost::shared_ptr
). لا تحاول استخدام std::auto_ptr
لهذا، فهو لن يعمل (لن حتى تجميع).
وشيء آخر أن نأخذ في الاعتبار، يجب تجنب استخدام <
مقارنة التكرارات في حلقة الخاص بك عندما يكون ذلك ممكنا، وأنها ستعمل فقط لالمكررات أن تصميم نموذج لمكرر الوصول العشوائي، مما يعني أنك لا يمكن أن تغير من التعليمات البرمجية لاستخدام مثل وstd::list
.
ونعم من الممكن، وفي واقع الأمر هو الضرورة م> لاستخدام مؤشرات إذا كنت تنوي ناقلات لتحتوي على كائنات من التسلسل الهرمي فئة بأكمله وليس من نوع واحد. (الفشل في استخدام مؤشرات سيؤدي إلى مشكلة اللعين rel="nofollow تشريح الاعتراض - جميع الكائنات بصمت تم تحويله إلى نوع الفئة الأساسية. لا تشخيص ذلك من خلال مترجم، ويكاد يكون من المؤكد ليس ما تريد).
class c
{
void virtual func();
};
class sc:public c
{
void func(){cout<<"using func";}
};
sc cobj;
vector<c*> cvect; // Note the type is "c*"
cvect.push_back(&cobj); // Note the "&"
vector<c*>::iterator citer;
for(citer=cvect.begin();citer != cvect.end();citer++) // Use "!=" not "<"
{
(*citer)->func();
}
لاحظ أن مع متجه من المؤشرات، على ما عليك القيام به إدارة الذاكرة الخاصة بك ، أو حتى نكون حذرين جدا - إذا كنت ستقوم باستخدام كائنات المحلية (كما سبق)، ويجب أن لا تسقط النطاق قبل يفعل الحاوية. إذا كنت تستخدم مؤشرات إلى الكائنات التي تم إنشاؤها مع new
، ستحتاج إلى delete
عليها يدويا قبل تدمير الحاوية. يجب عليك أن تنظر تماما باستخدام مؤشرات الذكية في هذه الحالة، مثل smart_ptr
التي تقدمها Boost
.
نعم، بالتأكيد.
// TestCPP.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <vector>
using namespace std;
class c
{
public:
void virtual func() = 0;
};
class sc:public c
{
public:
void func(){cout<<"using func";}
};
int _tmain(int argc, _TCHAR* argv[])
{
sc cobj;
vector<c*> cvect;
cvect.push_back(&cobj);
vector<c*>::iterator citer;
for(citer=cvect.begin();citer<cvect.end();citer++)
{
(*citer)->func();
}
return 0;
}
تجدر الإشارة إعلان vector<c*> cvect
واستخدام cvect.push_back(&cobj)
.
ومن التعليمات البرمجية المقدمة، كنت تستخدم مكرر بطريقة خاطئة. للوصول إلى عضو مكرر يشير إلى أنك يجب أن تستخدم *citer
بدلا من citer
وحدها.
لديك إنشاء vector<c*>
للمتجه من المؤشرات. ثم استخدم new
إلى تخصيص الذاكرة للكائنات ج ودفعهم إلى النواقل. أيضا، لا ننسى أن لديك لdelete
نفسك وvector.clear () لن تطلق سراح الذاكرة المخصصة للكائنات ج. لديك لتخزين ج كناقل للمؤشرات هنا، وإلا فإن الدعوة إلى وظيفة افتراضية لا تعمل.
تعزيز المكتبة الحاويات مؤشر . لديها العديد من المزايا أكثر من ناقل منتظم من المؤشرات، مثل:
my_container.push_back( 0 ); // throws bad_ptr
ptr_vector<X> pvec;
std::vector<X*> vec;
( *vec.begin() )->foo(); // call X::foo(), a bit clumsy
pvec.begin()->foo(); // no indirection needed