Если D - производный класс базового класса B, то вы можете назначить объект типа Derived переменной (или параметру) типа Base.
ПРИМЕР
class Pet
{
public:
string name;
};
class Dog : public Pet
{
public:
string breed;
};
int main()
{
Dog dog;
Pet pet;
dog.name = "Tommy";
dog.breed = "Kangal Dog";
pet = dog;
cout << pet.breed; //ERROR
Хотя указанное назначение разрешено, значение, присвоенное переменной pet, теряет поле породы. Это называется проблемой нарезки.
2. КАК ИЗМЕНИТЬ ПРОБЛЕМУ СЦЕПЛЕНИЯ
Чтобы устранить проблему, мы используем указатели на динамические переменные.
ПРИМЕР
Pet *ptrP;
Dog *ptrD;
ptrD = new Dog;
ptrD->name = "Tommy";
ptrD->breed = "Kangal Dog";
ptrP = ptrD;
cout << ((Dog *)ptrP)->breed;
В этом случае ни один из элементов данных или функций-членов динамической переменной, на которые указывает ptrD (объект класса потомка), будет потерян. Кроме того, если вам нужно использовать функции, функция должна быть виртуальной.
Я не знаю, почему вы думаете, что ваш процесс должен иметь доступ к 4 ГБ. Согласно Ограничениям памяти для выпуска Windows в MSDN, в 64-разрядной Windows 7, 32-разрядный процесс по умолчанию получает 2 ГБ. * Именно это и заканчивается.
So , есть ли способ обойти это?
Ну, вы можете создать пользовательскую сборку из 32-разрядного Python, которая использует флаг IMAGE_FILE_LARGE_ADDRESS_AWARE
, и перестроить numpy
и все ваши другие модули расширения. Я не могу обещать, что весь соответствующий код действительно безопасен для работы с флагом с большим адресом; есть хороший шанс, но если кто-то уже это сделал и не протестировал, «хороший шанс» - это лучший, кого, вероятно, узнают.
Или, что более очевидно, просто используйте 64-битный Python вместо этого .
Объем физической ОЗУ полностью не имеет значения. Кажется, вы думаете, что у вас есть «ограничение 8 ГБ» с 8 ГБ ОЗУ, но это не так, как это работает. Ваша система занимает всю вашу RAM плюс любое место подкачки, в котором она нуждается , и делит ее между приложениями; приложение может получить 20 ГБ виртуальной памяти, не получая ошибку памяти даже на машине 8 ГБ. Между тем, 32-разрядное приложение не имеет доступа к более чем 4 ГБ, и ОС будет использовать некоторые из этих адресных пространств (половина из них по умолчанию в Windows), поэтому вы можете получить только 2 ГБ даже на машине с 8 ГБ это ничего не работает. (Нельзя сказать, что когда-либо можно «ничего не запускать» на современной ОС, но вы знаете, что я имею в виду.)
Итак, почему это работает на вашем Linux-поле?
Поскольку ваш Linux-модуль настроен на предоставление 32-битных процессов 3,5 ГБ виртуального адресного пространства, или 3,99 ГБ, или ... Ну, я не могу сказать вам точный номер, но каждый дистрибутив, который я видел для много лет был настроен как минимум на 3,25 ГБ.
* Также обратите внимание, что вы даже не получаете полные 2 ГБ для своих данных; вашей программы. Большая часть того, что ОС и его драйверы делают доступными для вашего кода, находится в другой половине, но некоторые биты сидят в вашей половине, вместе с каждой загружаемой DLL и любым необходимым пространством и другими вещами. Это не слишком много, но это не ноль.
IMAGE_FILE_LARGE_ADDRESS_AWARE
- это всего лишь флаг в заголовке изображения (не то, что это когда-либо официально поддерживалось, но мы не судим;)). Кроме того, dlls не имеют права говорить в этом вопросе, чтобы начать, так что их не нужно менять в любом случае. – Voo 16 August 2013 в 23:54IMAGE_FILE_LARGE_ADDRESS_AWARE
из коробки; я предполагаю, что причина в том, что до сих пор ни один из разработчиков никогда не обнаружил, что стоит тестировать и / или очищать исходный код, потому что, если им действительно нужно больше 2 ГБ, они просто используют 64-битную сборку. Но это всего лишь предположение, поэтому мой ответ сказал, что есть хорошие шансы, что это сработает, но я не могу обещать. – abarnert 19 August 2013 в 20:22