The entry point for reading and writing Cifti data is the object CiftiFile.  To get a handle to a Cifti File, use the following syntax:
CiftiFile cf("testciftifile.dtseries.nii"), cf2;//starts on-disk reading, and makes an uninitialized second object
cf2.setWritingFile("testoutcifti.dtseries.nii");//prepare on-disk writing mode
//cf.convertToInMemory();//if you want to read entire file into memory now

CiftiFile gives access to the file in two parts, the Cifti XML, and the Cifti Matrix data.  To access the data use the following functions:

//get the CiftiXML object, containing mapping info for each dimension
const CiftiXML& xml = cf->getCiftiXML();
cf2->setCiftiXML(xml);//setting xml is required before writing rows of data, as the xml controls the dimensions and mapping info

//read/write Cifti rows
vector<float> scratchRow(cf.getDimensions()[0]);
//simplified functions for 2D only
cf.getRow(scratchRow.data(), 0);
cf2.setRow(scratchRow.data(), 0);
//example specifically for 3D cifti
vector<int64_t> indices(2, 0);//[0 0]
cf.getRow(scratchRow.data(), indices);
cf2.setRow(scratchRow.data(), indices);

//write current state to a new Cifti File, without changing what file subsequent setRow calls set data in (if any)
cf.writeFile("outputfile.dtseries.nii");

For more detailed information on how to manipulate Cifti data, look at the source files in the examples directory

Other references:

nitrc page:
http://www.nitrc.org/projects/cifti/

effectively same library, available under BSD 2-clause, and adapted to work with either libxml++ or qt:
https://github.com/Washington-University/CiftiLib
