Use pointers to Partitions in PartitionVector class (#759726)
The PartitionVector class is now internally using pointers to Partition objects and taking on management of their lifetimes. It therefore has to implement the Big 3: destructor, copy constructor and copy assignment operator [1][2]. This is because the implicitly-defined copy constructor and assignment operator perform memberwise "shallow copying" and the destructor does nothing. This not correct for classes which contain non-class types such as raw pointers. The semantics of the interface still copies each Partition object into the PartitionVector when they are added with push_back() and insert(). Note that a PartitionVector object is explicitly copy assigned in Win_GParted::Refresh_Visual(). They are also implicitly copied when (1) the implementing vector is resized larger to allow it to hold more pointers to Partition objects than it previously had capacity for; and (2) a Partition object is copied including the logicals PartitionVector member. [1] The rule of three/five/zero http://en.cppreference.com/w/cpp/language/rule_of_three [2] Rule of Three https://en.wikipedia.org/wiki/Rule_of_three_%28C%2B%2B_programming%29 Bug 759726 - Implement Partition object polymorphism
This commit is contained in:
parent
48d898ebfd
commit
06b8a3a14a
|
@ -14,9 +14,9 @@
|
|||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Minimal implementation of a class that behaves like a std::vector<Partition> which can
|
||||
* be used in it's place with minimal change to the existing GParted code which expects to
|
||||
* be working with a std::vector<Partition>.
|
||||
/* Minimal implementation of a class with some behaviours like a std::vector<Partition>.
|
||||
* However internally the class manages pointers to Partition objects allowing for
|
||||
* Partition object polymorphism.
|
||||
* Reference:
|
||||
* C++ Reference to std::vector
|
||||
* http://www.cplusplus.com/reference/vector/vector/
|
||||
|
@ -44,10 +44,13 @@ class PartitionVector; // mutually recursive classes.
|
|||
class PartitionVector {
|
||||
public:
|
||||
typedef size_t size_type;
|
||||
typedef std::vector<Partition>::iterator iterator;
|
||||
typedef std::vector<Partition *>::iterator iterator;
|
||||
|
||||
PartitionVector() {};
|
||||
~PartitionVector() {};
|
||||
PartitionVector( const PartitionVector & src );
|
||||
~PartitionVector();
|
||||
void swap( PartitionVector & other );
|
||||
PartitionVector & operator=( PartitionVector rhs );
|
||||
|
||||
// Iterators
|
||||
iterator begin() { return v.begin(); };
|
||||
|
@ -56,22 +59,21 @@ public:
|
|||
bool empty() const { return v.empty(); };
|
||||
|
||||
// Element access
|
||||
Partition & operator[]( size_type n ) { return v[n]; };
|
||||
const Partition & operator[]( size_type n ) const { return v[n]; };
|
||||
Partition & operator[]( size_type n ) { return *v[n]; };
|
||||
const Partition & operator[]( size_type n ) const { return *v[n]; };
|
||||
size_type size() const { return v.size(); };
|
||||
const Partition & front() const { return v.front(); };
|
||||
const Partition & back() const { return v.back(); };
|
||||
const Partition & front() const { return *v.front(); };
|
||||
const Partition & back() const { return *v.back(); };
|
||||
|
||||
// Modifiers
|
||||
void pop_back() { v.pop_back(); };
|
||||
void erase( const iterator position ) { v.erase( position ); };
|
||||
void clear() { v.clear(); };
|
||||
void push_back( const Partition & partition ) { v.push_back( partition ); };
|
||||
void insert( iterator position, const Partition & partition )
|
||||
{ v.insert( position, partition ); };
|
||||
void pop_back();
|
||||
void erase( const iterator position );
|
||||
void clear();
|
||||
void push_back( const Partition & partition );
|
||||
void insert( iterator position, const Partition & partition );
|
||||
|
||||
private:
|
||||
std::vector<Partition> v;
|
||||
std::vector<Partition *> v;
|
||||
};
|
||||
|
||||
} //GParted
|
||||
|
|
|
@ -31,6 +31,7 @@ src/OperationLabelFileSystem.cc
|
|||
src/OperationNamePartition.cc
|
||||
src/OperationResizeMove.cc
|
||||
src/Partition.cc
|
||||
src/PartitionVector.cc
|
||||
src/SWRaid_Info.cc
|
||||
src/TreeView_Detail.cc
|
||||
src/Utils.cc
|
||||
|
|
|
@ -47,6 +47,7 @@ gpartedbin_SOURCES = \
|
|||
OperationNamePartition.cc \
|
||||
OperationResizeMove.cc \
|
||||
Partition.cc \
|
||||
PartitionVector.cc \
|
||||
PipeCapture.cc \
|
||||
Proc_Partitions_Info.cc \
|
||||
SWRaid_Info.cc \
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
/* Copyright (C) 2015 Mike Fleetwood
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "../include/Partition.h"
|
||||
#include "../include/PartitionVector.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace GParted
|
||||
{
|
||||
|
||||
PartitionVector::PartitionVector( const PartitionVector & src )
|
||||
{
|
||||
v.resize( src.size() );
|
||||
for ( unsigned int i = 0 ; i < src.size() ; i ++ )
|
||||
v[i] = new Partition( src[i] );
|
||||
}
|
||||
|
||||
PartitionVector::~PartitionVector()
|
||||
{
|
||||
for ( unsigned int i = 0 ; i < v.size() ; i ++ )
|
||||
delete v[i];
|
||||
}
|
||||
|
||||
void PartitionVector::swap( PartitionVector & other )
|
||||
{
|
||||
std::swap( this->v, other.v );
|
||||
}
|
||||
|
||||
PartitionVector & PartitionVector::operator=( PartitionVector rhs )
|
||||
{
|
||||
// Copy assignment implemented using copy-and-swap idiom.
|
||||
// 1) Pass-by-value to get rhs variable copy constructed from source;
|
||||
// 2) Swap contents of this PartitionVector with rhs variable copy;
|
||||
// 3) Method returns, rhs variable goes out of scope and destructor called on old
|
||||
// this PartitionVector to delete owned Partitions.
|
||||
// Reference:
|
||||
// Wikibooks: More C++ Idioms / Copy-and-swap
|
||||
// https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Copy-and-swap
|
||||
rhs.swap( *this );
|
||||
return *this;
|
||||
}
|
||||
|
||||
void PartitionVector::pop_back()
|
||||
{
|
||||
delete v.back();
|
||||
v.pop_back();
|
||||
}
|
||||
|
||||
void PartitionVector::erase( const iterator position )
|
||||
{
|
||||
delete *position;
|
||||
v.erase( position );
|
||||
}
|
||||
|
||||
void PartitionVector::clear()
|
||||
{
|
||||
for ( unsigned int i = 0 ; i < v.size() ; i ++ )
|
||||
delete v[i];
|
||||
v.clear();
|
||||
}
|
||||
|
||||
void PartitionVector::push_back( const Partition & partition )
|
||||
{
|
||||
Partition * p = new Partition( partition );
|
||||
v.push_back( p );
|
||||
}
|
||||
|
||||
void PartitionVector::insert( iterator position, const Partition & partition )
|
||||
{
|
||||
Partition * p = new Partition( partition );
|
||||
v.insert( position, p );
|
||||
}
|
||||
|
||||
} //GParted
|
Loading…
Reference in New Issue